嵌入式学习的第二十一天-数据结构-双向链表
一、双向链表
1.定义
双向链表是在单链表的每个结点中,再设置一个指向其钱去节点的指针域。
typedef struct DulNode
{ElemType date;struct DulNode *pri;//直接前驱指针sturct DulNode *next;//直接后继指针
}DulNode,*DuLinkList;
2.双向链表的创建
struct DouLinkList* CreateDouLinkList()
{struct DouLinkList*dl = malloc(sizeof(struct DouLinkList));if(NULL == dl){fprintf(stderr, "CreatDouLinkList malloc");return NULL;} dl->head =NULL;dl->clen = 0;return dl;
}
3.双向链表的插入
(1)头插
int InsertHeadDouLinkList(struct DouLinkList*dl,struct DATATYPE*data)
{struct DouNode*newnode = malloc(sizeof( struct DouNode));if(NULL == newnode){fprintf(stderr, "InsertHeadDouLinkList malloc");return 1; }memcpy(&newnode->data,data,sizeof(struct DATATYPE));newnode->next = NULL;newnode->prev = NULL;newnode->next =dl->head;if(dl->head){dl->head->prev =newnode;}dl->head = newnode;dl->clen++;return 0;
}
(2)尾插
int InsertTailDouLinkList(struct DouLinkList*dl,struct DATATYPE*data)
{if(IsEmptyDouLinkList(dl)){return InsertHeadDouLinkList(dl,data);}else{ struct DouNode*tmp = dl->head;while(tmp->next){tmp = tmp->next;}struct DouNode*newnode = malloc(sizeof( struct DouNode));if(NULL == newnode){fprintf(stderr, "InsertTailDouLinkList malloc");return 1; }//初始化节点memcpy(&newnode->data,data,sizeof(struct DATATYPE));newnode->next = NULL;newnode->prev = NULL;//连接链表newnode->prev = tmp;tmp->next = newnode;dl->clen++;}return 0;
}
(3) 任意位置插
int InsertPosDouLinkList(struct DouLinkList*dl,struct DATATYPE*data,int pos)
{int len = GetSizeDouLinkList(dl);if(pos<0||pos>len){return 1;}if(0 == pos){return InsertHeadDouLinkList(dl,data);}else if(pos == len){return InsertTailDouLinkList(dl, data);}else{struct DouNode*newnode = malloc(sizeof( struct DouNode));if(NULL == newnode){fprintf(stderr, "InsertPosDouLinkList malloc");return 1; }//初始化节点memcpy(&newnode->data,data,sizeof(struct DATATYPE));newnode->next = NULL;newnode->prev = NULL;struct DouNode*tmp = dl->head;int i = 0;for(i = 0;i < pos;++i){tmp = tmp->next;}newnode->next=tmp;newnode->prev=tmp->prev;tmp->prev=newnode;newnode->prev->next=newnode;}return 0;
}
4.双向链表的遍历
int ShowDouLinkList(struct DouLinkList*dl,DIR dir)
{struct DouNode*tmp = dl->head;if(FORWADR == dir){while (tmp){printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);tmp=tmp->next;}}else if(BACKWADR == dir){while(tmp->next){tmp=tmp->next;}while(tmp){printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);tmp =tmp->prev;}}return 0;
}
5. vi Makefile(工程管理工具) :三个.c以上可使用
方法一:
a.out(目标):main.c ./doulink (依赖)gcc main.c doulink.c//前面空一个Tab键
clean:rm a.out
在终端敲make,进行编译,若要指定makefile ,加-f再加指定makefile
方法二:
#代表源文件
SRC += main.c(变量名任取)//指定变量
SRC += doulink.c
DST = app(可执行文件)CC = gcc//编译器
FLAG = -g
LIB = -lm$(DST):$(SRC)$(CC) $(SRC) $(FLAG) $(LIB)-o(指定名字) $(DST)
clean:rm $(DST)
6.双向链表的查找
struct DouNode * FindDouLinkList(struct DouLinkList*dl,char*name)
{if(IsEmptyDouLinkList(dl)){return NULL;}struct DouNode*tmp = dl->head;while(tmp){if(0 == strcmp(tmp->data.name,name)){return tmp;}tmp = tmp->next;}return NULL;
}
7.双向链表的修改
int ModifyDouLinkList(struct DouLinkList*dl,char*name,struct DATATYPE*data)
{struct DouNode*tmp = FindDouLinkList(dl, name);if(NULL == tmp){return 1;}memcpy(&tmp->data, data,sizeof(struct DATATYPE));return 0;
}
8.双向链表的销毁
int DestoryDouLinkList(struct DouLinkList*dl)
{while(1){struct DouNode*tmp = dl->head;if(NULL == tmp){break;}dl->head = dl->head->next;free(tmp);}free(dl);dl = NULL;return 0;
}
9.双向链表的删除
int DeleteDouLinkList(struct DouLinkList*dl,char*name)
{if(IsEmptyDouLinkList(dl)){return 1;}struct DouNode*tmp = FindDouLinkList(dl, name);if(tmp ==dl->head){dl->head =dl->head->next;tmp->next->prev = NULL;free(tmp);}else if(NULL == tmp->next){tmp->prev->next = NULL;free(tmp);}else{tmp->next->prev = tmp->prev;tmp->prev->next = tmp->next;free(tmp);}dl->clen--;return 0;
}
10.双向链表的逆序
int ReverseDouLinkList(struct DouLinkList*dl){struct DouNode*prev = NULL;struct DouNode*tmp = dl->head;struct DouNode*next = tmp->next;int len = GetSizeDouLinkList(dl);if(len < 2){return 1;}while(1){tmp->next = prev;tmp->prev = next;prev = tmp;tmp = next;if(NULL == tmp){break;}else{next = next->next;}}dl->head = prev;return 0;}