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\n",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\n",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\n",temp->data);
133         }else{
134             printf("%d->",temp->data);
135         }
136         temp=temp->next;
137     }
138 }

(1)声明用来遍历链表的指针 -------- * temp(用来遍历链表) 

(2)当节点不为零时,分尾节点和普通节点两种。循环输出普通节点 -> 输出尾节点 -> 跳出循环,程序结束

Posted on 2019-11-03 19:08  choco莉特  阅读(537)  评论(0编辑  收藏  举报