双向链表
- 双向结点构建:结点结构

#pragma mark - 定义结点 typedef struct Node{ struct Node *prior; struct Node *next; ElemType data; }Node; typedef struct Node *ModelList; - 初始化双向链表
#pragma mark - 创建双向链表 Status InitModelList(ModelList *list){ *list = (ModelList)malloc(sizeof(Node)); if (!list) { return ERROR; } (*list)->next = NULL; (*list)->prior = NULL; //注意头结点的data可以不用赋值 (*list)->data = -1; //增加结点 ModelList p = *list; int type; printf("输入结点的值,输入0则结束:\n"); while (1) { scanf("%d",&type); if (type == 0) { return OK; } //创建临时结点 ModelList temp = (ModelList)malloc(sizeof(Node)); temp->data = type; temp->next = NULL; temp->prior = NULL; //为临时结点建立关系 p->next = temp; temp->prior = p; p = temp; } return OK; } - 双向链表的遍历
#pragma mark - 遍历双向链表 Status TraversalList(ModelList list){ if (!list) { return ERROR; } printf("遍历双向链表开始:\n"); //除去头结点 ModelList temp = list->next; while (temp) { printf("%d\n",temp->data); temp = temp->next; } printf("遍历双向链表结束:\n"); return OK; } - 双向链表的插入:图示

需要注意的是插入时要区分是否是尾结点,因为尾结点的next-next = NULL;另一个就是插入时先处理插入位置后面结点再处理前面的结点
#pragma mark - 双向链表插入 Status InsertList(ModelList *list, int index, ElemType data){ if (!list) { return ERROR; } ModelList p = *list; ModelList temp = (ModelList)malloc(sizeof(Node)); if (!temp) { return ERROR; } temp->data = data; temp->next = NULL; temp->prior = NULL; //找到插入位置的前一个位置 for (int i = 1; i<index && p; i++) { p = p->next; } //如果没有找到插入的位置 if (!p) { return ERROR; } //需要独立处理是否是尾结点 if (p->next != NULL) {//插入的位置不是尾结点 temp->next = p->next; temp->next->prior = temp; temp->prior = p; p->next = temp; }else{//如果是最后一个结点 p->next = temp; temp->prior = p; } return ERROR; } - 双向链表的删除:图示

#pragma mark - 双向链表的删除 //按结点位置删除 Status DeleteListWithIndex(ModelList *list,int index){ if (!list) { return ERROR; } ModelList p = *list; int i = 1; //找到删除结点的前一个结点 while (i<index && p) { p = p->next; i++; } if (p->next == NULL || index<i) {//没有找删除的前一个结点 return ERROR; } //记录删除的结点 ModelList temp = p->next; p->next = temp->next; //如果删除的不是尾结点 if (temp->next != NULL) { temp->next->prior = p; } printf("删除的结点数值为:%4d",temp->data); free(temp); return OK; } //按结点内容删除 Status DeleteListWithData(ModelList *list,int data){ if (!list) { return ERROR; } ModelList p = *list; //记录删除结点的位置 int i = 1; //找到删除结点的前一个结点 while (p->next) { if (p->next->data == data) { break; } p = p->next; i++; } if (p->next == NULL) {//删除结点没有找到 return ERROR; } //记录删除的结点 ModelList temp = p->next; p->next = temp->next; //如果删除的不是尾结点 if (temp->next != NULL) { temp->next->prior = p; } printf("删除的结点位置为:%4d",i); free(temp); return OK; } - 双向链表指定位置结点的更新
#pragma mark - 双向链表指定位置结点数据更新 Status UpdataList(ModelList *list, int index, ElemType data){ if (!list || index<1) { return ERROR; } ModelList p = (*list)->next; int i = 1; while (i<index) { p = p->next; i++; } if (p == NULL) {//没有找到需要更新的结点 return ERROR; } p->data = data; return OK; }
双向循环链表
- 初始化双向循环链表

#pragma mark - 创建双向循环链表 Status InitModelList(ModelList *list){ *list = (ModelList)malloc(sizeof(Node)); if (!list) { return ERROR; } (*list)->next = (*list); (*list)->prior = (*list); //注意头结点的data可以不用赋值 (*list)->data = -1; //增加结点 ModelList p = *list; int type; printf("输入结点的值,输入0则结束:\n"); while (1) { scanf("%d",&type); if (type == 0) { return OK; } //此处使用的是后插法 //创建结点 ModelList temp = (ModelList)malloc(sizeof(Node)); temp->data = type; //为临时结点建立关系 p->next = temp; temp->prior = p; temp->next = *list; //头结点的前驱指向新的结点 (*list)->prior = temp; //将p指向新建的结点,这样p就指向了最后的结点 p = p->next; } return OK; } - 遍历双向循环链表
#pragma mark - 遍历双向循环链表 Status TraversalList(ModelList list){ if (!list) { return ERROR; } printf("遍历双循环向链表开始:\n"); //除去头结点 ModelList temp = list->next; while (temp != list) { printf("%d\n",temp->data); temp = temp->next; } printf("遍历双向循环链表结束:\n"); return OK; } - 双向循环链表的插入

#pragma mark - 双向循环链表插入 Status InsertList(ModelList *list, int index, ElemType data){ if (!list || index<1) { return ERROR; } ModelList temp,p; int i; p = *list; temp = (ModelList)malloc(sizeof(Node)); if (!temp) { return ERROR; } temp->data = data; //找到插入的前一个结点,i<=index,如果i<index,则会导致无法插入到最后一个 for (i = 1; p->next != *list && i<=index; p = p->next,i++) { } temp->next = p->next; temp->prior = p; p->next = temp; if (temp->next != *list) {//插入的位置不是尾结点 temp->next->prior = temp; }else{ (*list)->prior = temp; } return OK; } - 双向循环链表的删除

#pragma mark - 双向循环链表的删除 Status DeleteList(ModelList *list,int index){ if (!list || index<1) { return ERROR; } ModelList p = *list; if (p->next == *list) {//如果只有头结点则直接退出 return ERROR; } int i = 1; //找到删除节点的前一个结点 while (i<index) { p = p->next; if (p->next == *list && (*list)->next == p) {//此时表明只有一个结点了,被删除的结点前一个结点就是头结点 p = *list; break; } //此处双向循环链表删除没有循环一遍,只有找到需要删除的位置才会结束 if (p != *list) { i++; } } //删除的结点 ModelList deleTemp = p->next; ElemType data = deleTemp->data; p->next = deleTemp->next; deleTemp->next->prior = p; free(deleTemp); printf("删除结点的值为:%2d\n",data); return OK; } - 双向循环链表根据位置查找结点
#pragma mark - 双向链表根据位置查找结点
Status SearchList(ModelList *list,int index){
if (!list) {
return ERROR;
}
int i = 1;
ModelList p = *list;
while (i<=index) {
p = p->next;
if (p->next == *list && (*list)->next == p) {//此时表明只有一个结点了
break;
}
//此处双向循环链表删除没有循环一遍,只有找到需要删除的位置才会结束
if (p != *list) {
i++;
}
}
printf("结点的值为:%2d\n",p->data);
return OK;
}