1 #include<stdlib.h>
2 #include<iostream>
3 #include<stdio.h>
4 #include<string>
5 using namespace std;
6 typedef struct Node{
7 int data;
8 struct Node* next;
9 struct Node* pre;
10 }dnode;
11
12 dnode *create()
13 {
14 dnode*head,*p,*s;
15 int x,cycle=1;
16 head=(dnode*)malloc(sizeof(dnode));
17 p=head;
18 cout<<"\nPlease input the data:"<<endl;
19 while(cycle)
20 {
21 cin>>x;
22 if(x!=0)
23 {
24 s=(dnode*)malloc(sizeof(dnode));
25 s->data=x;
26 p->next=s;
27 s->pre=p;
28 p=s;
29 }
30 else cycle=0;
31 }
32 head=head->next;
33 head->pre=NULL;
34 p->next=NULL;
35 cout<<"\nThe head data is"<<head->data<<endl;
36 return head;
37 }
38
39 dnode* del(dnode* head,int num)
40 {
41 dnode *p1,*p2;
42 p1=head;
43 while(num!=p1->data&&p1->next!=NULL)
44 {
45 p1=p1->next;
46 }
47 if(num==p1->data)
48 {
49 if(p1==head)
50 {
51 head=head->next;
52 head->pre=NULL;
53 free(p1);
54 }
55 else if(p1->next==NULL)
56 {
57 p1->pre->next=NULL;
58 free(p1);
59 }
60 else
61 {
62 p1->next->pre=p1->pre;
63 p1->pre->next=p1->next;
64 free(p1);
65 }
66 }
67 else
68 cout<<"could not been found "<<num<<endl;
69 return head;
70 }
71
72 dnode* insert(dnode* head,int num)
73 {
74 dnode *p0,*p1;
75 p1=head;
76 p0=(dnode*)malloc(sizeof(dnode));
77 p0->data=num;
78 while(p0->data>p1->data&&p1->next!=NULL)
79 {
80 p1=p1->next;
81 }
82 if(p0->data<=p1->data)
83 {
84 if(head==p1)
85 {
86 p0->next=p1->next;
87 p1->pre=p0;
88 head=p0;
89 }
90 else
91 {
92 p0->next=p1;
93 p1->pre->next=p0;
94 p0->pre=p1->pre;
95 p1->pre=p0;
96 }
97 }
98 else
99 {
100 p1->next=p0;
101 p0->pre=p1;
102 p0->next=NULL;
103 }
104 return head;
105 }
106
107 void print(dnode* head)
108 {
109 dnode* p=head;
110 while(p->next!=NULL)
111 {
112 cout<<p->data<<"->";
113 p=p->next;
114 }
115 cout<<endl;
116 }
117 int main()
118 {
119 dnode *head,stud;
120 int n,del_num,insert_num;
121 head=create();
122 print(head);
123 cout<<"input delete number:";
124 cin>>del_num;
125 head=del(head,del_num);
126 print(head);
127 cout<<"please input the insert data:";
128 cin>>insert_num;
129 head=insert(head,insert_num);
130 print(head);
131 return 0;
132 }

雙鏈表
1、雙向鏈表(Doubly Linked List)
雙(向)鏈表中有兩條方向不同的鏈,即每個結點中除next域存放後繼結點地址外,還增加一個指向其直接前趨的指針域prior。
注意:
①雙鏈表由頭指針head惟一確定的。
②帶頭結點的雙鏈表的某些運算變得方便。
③將頭結點和尾結點鏈接起來,為雙(向)循環鏈表。
2、雙向鏈表的結點結構和形式描述
①結點結構(見上圖a)
②形式描述
typedef struct dlistnode{
DataType data;
struct dlistnode *prior,*next;
}DListNode;
typedef DListNode *DLinkList;
DLinkList head;
3、雙向鏈表的前插和刪除本結點操作
刻畫雙鏈表結構的對稱性的語句:p→prior→next== p→next→prior;由於雙鏈表的對稱性,在雙鏈表能能方便地完成各種插入、刪除操作。
①雙鏈表的前插操作
void DInsertBefore(DListNode *p,DataType x)
{//在帶頭結點的雙鏈表中,將值為x的新結點插入*p之前,設p≠NULL
DListNode *s=malloc(sizeof(DListNode));//①
s->data=x;//②
s->prior=p->prior;//③
s->next=p;//④
p->prior->next=s;//⑤
p->prior=s;//⑥
}
②雙鏈表上刪除結點*p自身的操作
void DDeleteNode(DListNode *p)
{//在帶頭結點的雙鏈表中,刪除結點*p,設*p為非終端結點
p->prior->next=p->next;//①
p->next->prior=p->prior;//②
free(p);//③
}
注意:
與單鏈表上的插入和刪除操作不同的是,在雙鏈表中插入和刪除必須同時修改兩個方向上的指針。
上述兩個算法的時間復雜度均為O(1)。
參考資料:baike.baidu.com/view/1850617.htm
刪除單鏈表中的某個結點時,一定要得到待刪除結點的前驅,得到該前驅有兩種方法,第一種方法是在定位待刪除結點的同時一路保存當前結點的前驅。第二種方法是在定位到待刪除結點之後,重新從單鏈表表頭開始來定位前驅。盡管通常會采用方法一。但其實這兩種方法的效率是一樣的,指針的總的移動操作都會有2*i次。而如果用雙向鏈表,則不需要定位前驅結點。因此指針總的移動操作為i次。