1 #include <stdio.h> //增+删+改+查+初始化+输出 2 #include <stdlib.h> 3 typedef struct line{ 4 struct line * prior; 5 int data; 6 struct line * next; 7 }line; 8 //双链表的创建 9 line* initLine(line * head); 10 //双链表插入元素,add表示插入位置 11 line * insertLine(line * head,int data,int add); 12 //双链表删除指定元素 13 line * delLine(line * head,int data); 14 //双链表中查找指定元素 15 int selectElem(line * head,int elem); 16 //双链表中更改指定位置节点中存储的数据,add表示更改位置 17 line *amendElem(line * p,int add,int newElem); 18 //输出双链表的实现函数 19 void display(line * head); 20 int main() { 21 line * head=NULL; 22 //创建双链表 23 head=initLine(head); 24 display(head); 25 //在表中第 3 的位置插入元素 7 26 head=insertLine(head, 7, 3); 27 display(head); 28 //表中删除元素 2 29 head=delLine(head, 2); 30 display(head); 31 32 printf("元素 3 的位置是:%d ",selectElem(head,3)); 33 //表中第 3 个节点中的数据改为存储 6 34 head = amendElem(head,3,6); 35 display(head); 36 return 0; 37 } 38 line* initLine(line * head){ 39 head=(line*)malloc(sizeof(line)); 40 head->prior=NULL; 41 head->next=NULL; 42 head->data=1; 43 line * list=head; 44 for (int i=2; i<=5; i++) { 45 line * body=(line*)malloc(sizeof(line)); 46 body->prior=NULL; 47 body->next=NULL; 48 body->data=i; 49 50 list->next=body; 51 body->prior=list; 52 list=list->next; 53 } 54 return head; 55 } 56 line * insertLine(line * head,int data,int add){ 57 //新建数据域为data的结点 58 line * temp=(line*)malloc(sizeof(line)); 59 temp->data=data; 60 temp->prior=NULL; 61 temp->next=NULL; 62 //插入到链表头,要特殊考虑 63 if (add==1) { 64 temp->next=head; 65 head->prior=temp; 66 head=temp; 67 }else{ 68 line * body=head; 69 //找到要插入位置的前一个结点 70 for (int i=1; i<add-1; i++) { 71 body=body->next; 72 } 73 //判断条件为真,说明插入位置为链表尾 74 if (body->next==NULL) { 75 body->next=temp; 76 temp->prior=body; 77 }else{ 78 body->next->prior=temp; 79 temp->next=body->next; 80 body->next=temp; 81 temp->prior=body; 82 } 83 } 84 return head; 85 } 86 line * delLine(line * head,int data){ 87 line * temp=head; 88 //遍历链表 89 while (temp) { 90 //判断当前结点中数据域和data是否相等,若相等,摘除该结点 91 if (temp->data==data) { 92 temp->prior->next=temp->next; 93 temp->next->prior=temp->prior; 94 free(temp); 95 return head; 96 } 97 temp=temp->next; 98 } 99 printf("链表中无该数据元素"); 100 return head; 101 } 102 //head为原双链表,elem表示被查找元素 103 int selectElem(line * head,int elem){ 104 //新建一个指针t,初始化为头指针 head 105 line * t=head; 106 int i=1; 107 while (t) { 108 if (t->data==elem) { 109 return i; 110 } 111 i++; 112 t=t->next; 113 } 114 //程序执行至此处,表示查找失败 115 return -1; 116 } 117 //更新函数,其中,add 表示更改结点在双链表中的位置,newElem 为新数据的值 118 line *amendElem(line * p,int add,int newElem){ 119 line * temp=p; 120 //遍历到被删除结点 121 for (int i=1; i<add; i++) { 122 temp=temp->next; 123 } 124 temp->data=newElem; 125 return p; 126 } 127 //输出链表的功能函数 128 void display(line * head){ 129 line * temp=head; 130 while (temp) { 131 if (temp->next==NULL) { 132 printf("%d ",temp->data); 133 }else{ 134 printf("%d->",temp->data); 135 } 136 temp=temp->next; 137 } 138 }
1.初始化:
38 line* initLine(line * head){ 39 head=(line*)malloc(sizeof(line)); 40 head->prior=NULL; 41 head->next=NULL; 42 head->data=1; 43 line * list=head; 44 for (int i=2; i<=5; i++) { 45 line * body=(line*)malloc(sizeof(line)); 46 body->prior=NULL; 47 body->next=NULL; 48 body->data=i; 49 50 list->next=body; 51 body->prior=list; 52 list=list->next; 53 } 54 return head; 55 }
(1)malloc申请第一个结点,赋给指向该结点(空间)的指针------- * head(用来代表该链表)【与单链表不同:不需要头结点】
(2)第一个节点的prior属性赋值为空;
(3)第一个节点的next属性赋值为空;
(4)第一个节点的data属性赋值
(5)声明用来遍历链表的指针------- * list (用来遍历链表)
(6)循环创建节点------利用malloc创建 ,赋给指向新申请的节点的指针------- * body(用来代表新申请的节点)
1>为新节点的prior指向为空
2>为新节点的next指向为空
3>为新节点的data赋值
4>第一个结点的next指向新节点 list->next=body;
5>新节点的prior指向第一个节点 body->prior=list
6>将遍历链表的指针后移到下一个节点 list=list->next
2.插入:
56 line * insertLine(line * head,int data,int add){ 57 //新建数据域为data的结点 58 line * temp=(line*)malloc(sizeof(line)); 59 temp->data=data; 60 temp->prior=NULL; 61 temp->next=NULL; 62 //插入到链表头,要特殊考虑 63 if (add==1) { 64 temp->next=head; 65 head->prior=temp; 66 head=temp; 67 }else{ 68 line * body=head; 69 //找到要插入位置的前一个结点 70 for (int i=1; i<add-1; i++) { 71 body=body->next; 72 } 73 //判断条件为真,说明插入位置为链表尾 74 if (body->next==NULL) { 75 body->next=temp; 76 temp->prior=body; 77 }else{ 78 body->next->prior=temp; 79 temp->next=body->next; 80 body->next=temp; 81 temp->prior=body; 82 } 83 } 84 return head; 85 }
(1)malloc申请新结点,赋给指向该结点的指针------- * temp (用来代表新申请的节点)
(2)第一个节点的prior属性赋值为空;
(3)第一个节点的next属性赋值为空;
(4)第一个节点的data属性赋值;
(5)判断是否插入到第一个位置:
i f 链表头: 1>新节点的next指向head(此处的head不是代表整个链表,而是代表链表的第一个节点) temp->next=head;
2>head的prior指向新节点 head->prior=temp;
3>将head重新指向第一个节点(已经插入后的) head=temp;
else 非链表头:1>声明用来遍历链表的指针------- * body (用来遍历链表)
2>循环找插入位置的前一个节点
3> i f 前一个节点的next为空 ----插入链表尾
1> 前一个节点的next指向新节点 body->next=temp;
2> 新节点的prior指向找见的前一个节点 temp->prior=body;
else -------- 链表中间插入 { 分别称为节点a (前一个节点 body) -> 新节点(新节点 temp) -> 节点b(后一个节点 body->next)}
1>节点b的prior指向新节点 body->next->prior=temp;
2>新节点的next指向节点b temp->next=body->next;
3>节点a的next指向新节点 body->next=temp;
4>新节点的prior指向节点a temp->prior=body;
3.删除:
86 line * delLine(line * head,int data){ 87 line * temp=head; 88 //遍历链表 89 while (temp) { 90 //判断当前结点中数据域和data是否相等,若相等,摘除该结点 91 if (temp->data==data) { 92 temp->prior->next=temp->next; 93 temp->next->prior=temp->prior; 94 free(temp); 95 return head; 96 } 97 temp=temp->next; 98 } 99 printf("链表中无该数据元素"); 100 return head; 101 }
(1)声明用来遍历链表的指针 -------- * temp (用来遍历链表)
(2)当指针不为0时
i f 当前指针所指节点data属性等于要找的data { 分别称为节点a(temp->prior) 节点b(要删除的节点 temp) 节点c(temp->next)}
1> 节点a的next指向节点c temp->prior->next=temp->next;
2>节点c的prior指向节点a temp->next->prior=temp->prior;
3>释放节点b
else 指针继续移向下一个节点 直到找见要找的data
4.查找元素n的位置:
102 //head为原双链表,elem表示被查找元素 103 int selectElem(line * head,int elem){ 104 //新建一个指针t,初始化为头指针 head 105 line * t=head; 106 int i=1; 107 while (t) { 108 if (t->data==elem) { 109 return i; 110 } 111 i++; 112 t=t->next; 113 } 114 //程序执行至此处,表示查找失败 115 return -1; 116 }
(1)声明用来遍历链表的指针 -------- * t(用来遍历链表)
(2)循环查找:如果找见了就返回位置(这里用 i 来记录);找不见就 i++ 指针下移 一直循环,直到找见为止
5.修改:
//更新函数,其中,add 表示更改结点在双链表中的位置,newElem 为新数据的值 118 line *amendElem(line * p,int add,int newElem){ 119 line * temp=p; 120 //遍历到被删除结点 121 for (int i=1; i<add; i++) { 122 temp=temp->next; 123 } 124 temp->data=newElem; 125 return p; 126 }
(1)声明用来遍历链表的指针 -------- * temp(用来遍历链表)
(2)循环找到被删除节点(前几篇随笔有详细介绍~欢迎看唠~)
(3)修改数据域
6.输出:
127 //输出链表的功能函数 128 void display(line * head){ 129 line * temp=head; 130 while (temp) { 131 if (temp->next==NULL) { 132 printf("%d ",temp->data); 133 }else{ 134 printf("%d->",temp->data); 135 } 136 temp=temp->next; 137 } 138 }
(1)声明用来遍历链表的指针 -------- * temp(用来遍历链表)
(2)当节点不为零时,分尾节点和普通节点两种。循环输出普通节点 -> 输出尾节点 -> 跳出循环,程序结束