玳瑁的嵌入式日记D21-08020(数据结构)

双向链表

double link list

typedef struct dou_node {

DATATYPE data;

struct dou_node *prev;

struct dou_node *next;

}DouLinkNode;


双向链表:

节点 = 数据 + NEXT +PREV .

手撕代码(增加+删除)

增加,删除的操作, 需要 tmp 停止待操作节点的前一节点上。

查找操作进行了扩展,回调函数(函数指针)。解耦合,扩展功能。


查找 顺序表O(1) 链表 O(n)

插入和删除 顺序表 O(n) 链表 O(1)

空间性能

顺序表 需要预先分配空间,大小固定

链表 不需要预先分配,大小可变,动态分配


int InsertHeadDouLinkList(DouLinkList *list,DATATYPE *data)

{

DouLinkNode *newnode = (DouLinkNode*)malloc(sizeof(DouLinkNode));

if ( NULL == newnode )

{

perror( "IsertHeadDouLinkList malloc error" );

return 1;

}

memcpy(&newnode->data,data,sizeof(DATATYPE));

newnode->prev = NULL;

newnode->next = NULL;

if ( IsEmptyLinkList(list) )

{

list->head = newnode;

}

else{

newnode->next = list->head;

list->head->prev = newnode;

list->head = newnode;

}

list->clen++;

return 0;

}

int InsertTailDouLinkList(DouLinkList *dl, DATATYPE *data)

{

if (IsEmptyLinkList(dl))

{

return InsertHeadDouLinkList(dl, data);

}

else

{

DouLinkNode *newnode = malloc(sizeof(DouLinkNode));

if (NULL == newnode)

{

perror("InsertTailDouLinkList malloc");

return 1;

}

memcpy(&newnode->data, data, sizeof(DATATYPE));

newnode->next = NULL;

newnode->prev = NULL;

DouLinkNode *tmp = dl->head;

while (tmp->next)

{

tmp = tmp->next;

}

newnode->prev = tmp;
tmp->next = newnode;

}

dl->clen++;

return 0;

}

int InsertPosLinkList(DouLinkList *list, DATATYPE *data,int pos)

{

if(pos<0 || pos > list->clen)

{

printf("InsertPosLinkList pos error\n");

return 1;

}

if(pos == 0)

{

return InsertHeadDouLinkList(list,data);

}

else if(pos == list->clen)

{

return InsertTailDouLinkList(list, data);

}else

{

DouLinkNode *newnode = malloc(sizeof(DouLinkNode));

if(NULL == newnode)

{

perror("InsertPosLinkList malloc error");

return 1;

}

memcpy(&newnode->data,data,sizeof(DATATYPE));

newnode->next = NULL;

newnode->prev = NULL;

DouLinkNode *tmp = list->head;

for(int i = 0; i < pos; i++)

{

tmp = tmp->next;

}

newnode->next = tmp;

newnode->prev = tmp->prev;

tmp->prev->next = newnode;

tmp->prev = newnode;

list->clen++;

}

return 0;

}


gdb


typedef enum {DIR_FORWARD,DIR_BACKWARD}DIRECT; //枚举

int ShowLinkList(DouLinkList *list,DIRECT direct)

{

DouLinkNode *tmp = list->head;

if(DIR_FORWARD == direct)

{

while(tmp)

{

printf("%s \n",tmp->data.data);

tmp = tmp->next;

}

}else

{

while(tmp->next)

{

tmp = tmp->next;

} // 移到最后

while(tmp)

{

printf("%s \n",tmp->data.data);

tmp = tmp->prev;

}

}

return 0;

}

int ReviseLinkList(DouLinkList *list)

{

if(list == NULL|| list->clen == 0)

{

printf("RviseLinkList error");

return 1;

}

DouLinkNode *prev = NULL;

DouLinkNode *curr = list->head;

DouLinkNode *next = NULL;

while(curr!=NULL)

{

next = curr->next;
prev = curr->prev;

curr->next = prev;//后移

prev = curr;

curr = next;

}

list->head = prev;

return 0;

}


DouLinkNode *FindDouLinkList(DouLinkList *dl,PFUN fun, void*arg)

{

DouLinkNode* tmp = dl->head;

while(tmp)

{

**//**if(0==strcmp(tmp->data.name,name))

if ( fun ( &tmp->data , arg))

{

return tmp;

}

tmp=tmp->next;

}

return NULL;

}

int findperbyname(DATATYPE*data,void* arg)

{

// 从void* -> 其他类型指针,需要强转

return 0 == strcmp(data->name,(char*)arg);

}

int findperbyage(DATATYPE*data,void* arg)

{

// 从void* -> 其他类型指针,需要强转

return data->age == *(int*)arg;;

}


printf("------------------------find-----------------------------\n");

char want_name[] = "lisi";

int age =50;

DouLinkNode* tmp = FindDouLinkList(list,findperbyname ,want_name);

if (NULL == tmp)

{

printf("cant find per %s\n",want_name);

}

else

{

printf("find it,name:%s score:%d\n",tmp->data.name,tmp->data.score);

}