双向链表
1,双向链表节点
2,具体操作
(1)定义结点结构体
```c typedef int data_t; //定义结点结构体 typedef struct node{ data_t data; //数据域 struct node *front; //保存上一个结点的地址 struct node *next; //保存下一个结点的地址 }doublelist; ```
(2)创建一个空的链表
```c doublelist *Head = NULL; ```
(3)尾插法插入数据
```c //尾插法插入数据 void InsertDataByTail(doublelist **head, data_t value) { //申请空间并赋值 doublelist *temp = (doublelist *)malloc(sizeof(doublelist)); temp->data = value; temp->front = NULL; temp->next = NULL; if(*head == NULL) { //如果链表为空,则指针保存第一个插入结点的地址 *head = temp; //让结点的两个指针域保存NULL表示没有其他结点 (*head)->front = NULL; (*head)->next = NULL; } else { //如果不为空,先找到最后一个结点 doublelist *p = *head; while(p->next != NULL) { p = p->next; } //将最后一个结点的地址保存在新插入的结点的front指针里面 temp->front = p; //将新插入结点的地址保存在最后一个结点的next指针里面 p->next = temp; } return ;} ```
(4)打印数据
```c //打印数据 void PrintData(doublelist *head){ printf("%d ", head->data); while(head->next != NULL) { printf("%d ", head->next->data); head = head->next; } putchar(10); printf("************************************\n"); while(head != NULL) { printf("%d ", head->data); head = head->front; } putchar(10); } ```
(5)头删法删除数据,返回要删除的结点的数据
```c //头删法删除数据 data_t DeleteDataOnHead(doublelist **head){ if(*head == NULL) { printf("链表为空不能删除数据了\n"); return (data_t)-1; } doublelist *temp = *head; data_t value = temp->data; //让指针保存新的头结点的地址 *head = (*head)->next; //让当前结点的front指针域保存NULL (*head)->front = NULL; free(temp); temp = NULL; return value; } ```
(6)插入并排序
```c //插入并排序 void InsertDataAndSort(doublelist **head, data_t value){ doublelist *temp = (doublelist *)malloc(sizeof(doublelist)); temp->data = value; temp->front = NULL; temp->next = NULL; if(*head == NULL) { //如果链表中没有数据,则用指针保存新插入结点的地址 *head = temp; (*head)->front = NULL; (*head)->next = NULL; } else { //如果新插入的结点的数据小于等于第一个结点 if((*head)->data >= temp->data) { //新插入的结点的next保存原本的第一个结点的地址 temp->next = *head; //原本的第一个结点的front保存新插入结点的地址 (*head)->front = temp; //指针保存新插入结点的地址 *head = temp; (*head)->front = NULL; } else { doublelist *p = *head; while(p->next != NULL && p->next->data < temp->data) { p = p->next; } //如果p结点后面没有数据 if(p->next == NULL) { //类似尾插法 p->next = temp; temp->front = p; } //如果p结点后面有数据 else { //将新插入结点的地址保存在p后一个结点的front指针里面 p->next->front = temp; //将p后一个结点的地址保存在新插入结点的next指针里面 temp->next = p->next; //将新插入结点的地址保存在p的结点的next指针里面 p->next = temp; //将p的结点的地址保存在新插入结点的front指针里面 temp->front = p; } } } } ```