双向链表节点的建立,头尾插,删除及正反向遍历

单链表存在一定的弊端,就是查找数据和删除数据的时候比较麻烦,而双链表的出现就是为了解决它的弊端:

双链表的引入是为了解决单链表的不足:
(1)双链表可以往前遍历,也可以往后遍历,具有两个方向
双链表的节点 = 有效数据 + 两个指针(分别指向前一个节点和后一个节点)
单向,双向链表的图形结构描述:

struct single_list 

    数据域; 
    指针域(后向指针) ;  
};

struct double_list 

    数据域; 
    指针域(前向指针) ; 
    指针域(后向指针) ;  
}; 

双向链表的基本操作和单向链表原理一致,所以这篇省略了注释[具体参见上一篇:

单向链表节点的建立,头尾插,打印,删除及逆序],双向链表在删除节点时并不必另设指针保存被删除节点的前一节点,较为方便

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 
  5 struct double_list {
  6     int data;
  7     struct double_list* prev;
  8     struct double_list* next;
  9 };
 10 typedef struct double_list DL;
 11 //创建节点
 12 DL* make_node(int data)
 13 {
 14     DL* p = (DL*)malloc(sizeof(DL));
 15     if (NULL == p)
 16     {
 17         printf("fail to malloc
");
 18         return    NULL;
 19     }
 20     memset(p, 00, sizeof(DL));
 21     p->data = data;;
 22     p->prev = NULL;
 23     p->next = NULL;
 24 }
 25 //尾插节点
 26 void tail_add(DL* ph, DL* new1)
 27 {
 28     DL* a = ph;
 29     while (NULL != a->next)
 30     {
 31         a = a->next;
 32     }
 33     a->next = new1;
 34     new1->prev = a;
 35     new1->next = NULL;
 36 }
 37 //头插节点
 38 void top_add(DL* ph, DL* new1)
 39 {
 40     ph->next->prev = new1;
 41     new1->next = ph->next;
 42     new1->prev = ph;
 43 }
 44 //删除节点
 45 int delete_node(DL* ph, int data)
 46 {
 47     DL* a = ph;
 48     while (NULL != a->next)
 49     {
 50         a = a->next;
 51         if (data == a->data)
 52         {
 53             //两种情况
 54             if (NULL != a->next) //下一个节点不为空
 55             {
 56                 a->prev->next = a->next;
 57                 a->next->prev = a->prev;
 58                 free(a);
 59             }
 60             else//下一个节点为空
 61             {
 62                 a->prev->next = NULL;
 63                 free(a);
 64             }
 65             printf("Successfully delete!
");
 66             return 0;
 67         }
 68 
 69     }
 70     printf("NOT FOUND!N");
 71     return -1;
 72 
 73 }
 74 
 75 //正向遍历链表
 76 void list_positive_traversal(DL* ph)
 77 {
 78     DL* a = ph;
 79     while (NULL != a->next)
 80     {
 81         a = a->next;
 82         printf("%d	", a->data);
 83     }
 84     printf("
");
 85 }
 86 
 87 //反向遍历链表
 88 void list_reverse_traversal(DL* ph)
 89 {
 90     DL* a = ph;
 91     while (NULL != a->next)
 92     {
 93         a = a->next;
 94     }
 95     while (NULL != a->prev)
 96     {
 97         printf("%d	", a->data);
 98         a = a->prev;
 99     }
100     printf("
");
101 }
102 int main()
103 {
104     int data;
105     DL* header = make_node(0);
106     
107     int N = 0;
108     printf("How many numbers do you want?
");
109     scanf("%d", &N);
110     getchar();
111     for (int i = 0; i < N; i++)//创建出N个节点并实现尾插
112     {
113         printf("<%d>", i + 1);
114         scanf("%d", &data);
115         getchar();
116         tail_add(header, make_node(data));
117     }
118     printf("list:
");
119     list_positive_traversal(header);
120 
121     printf("Do you want to delete node? [1--yes;0--no]
");
122     int r;
123     scanf("%d", &r);
124     getchar();
125     while (r)
126     {
127         printf("Which number will you delete?
");
128         int n;
129         scanf("%d", &n);
130         getchar();
131         delete_node(header, n);
132         printf("Do you want to delete node? [1--yes;0--no]
");
133         scanf("%d", &r);
134     }
135 
136     printf("positive traversal:
");
137     list_positive_traversal(header);
138 
139     printf("reverse traversal:
");
140     list_reverse_traversal(header);
141 
142     free(header);
143     return 0;
144 }

测试结果如下:

天涯犹在,不诉薄凉。
原文地址:https://www.cnblogs.com/Knight02/p/14334372.html