1 #include<iostream>
2 using namespace std;
3
4 #define OK 1
5 #define ERROR 0
6 #define OVERFLOW -2
7 typedef int Status; //Status 是函数返回值类型,其值是函数结果状态代码。
8 typedef int ElemType; //ElemType 为可定义的数据类型,此设为int类型
9
10 typedef struct LNode
11 {
12 ElemType data; //结点的数据域
13 struct LNode *next; //结点的指针域
14 }LNode,*LinkList; //LinkList为指向结构体LNode的指针类型
15
16
17 Status InitList_L(LinkList &L){ //算法2.5 单链表的初始化
18 //构造一个空的单链表L
19 L=new LNode; //生成新结点作为头结点,用头指针L指向头结点
20 L->next=NULL; //头结点的指针域置空
21 return OK;
22 }
23
24 Status ListInsert_L(LinkList &L,int i,ElemType &e){ //算法2.8 单链表的插入
25 //在带头结点的单链表L中第i个位置之前插入元素e
26 int j;
27 LinkList p,s;
28 p=L;j=0;
29 while(p && j<i-1){p=p->next;++j;} //刚好指向第i-1个节点
30 if(!p||j>i-1) return ERROR; //i大于表长+1或者小于1 当p不为空时如果i小于1的话则插入失败,如果p为空的话表明i大于表长
31 s=new LNode; //生成新结点s p指向当前第i-1的节点位置
32 s->data=e; //将结点s的数据域置为e
33 s->next=p->next; //将结点s插入L中
34 p->next=s;
35 return OK;
36 }//ListInsert_L
37
38 void CreateList_F(LinkList &L,int n){ //算法2.10 (前插法)创建单链表
39 //逆位序输入n个元素的值,建立到头结点的单链表L
40 LinkList p;
41 L=new LNode;
42 L->next=NULL; //先建立一个带头结点的空链表
43 cout<<"请输入 "<<n<<" 个数(以空格隔开,按回车结束):";
44 for(int i=n;i>0;--i){
45 p=new LNode; //生成新结点
46 cin>>p->data; //输入元素值
47 p->next=L->next;
48 L->next=p; //插入到表头
49 }
50 }//CreateList_F
51
52 void CreateList_L(LinkList &L,int n){ //算法2.11 (后插法)创建单链表
53 //正位序输入n个元素的值,建立到头结点的单链表L
54 LinkList r,p;
55 L=new LNode;
56 L->next=NULL; //先建立一个带头结点的空链表
57 r=L; //尾指针r指向头结点
58 cout<<"请输入 "<<n<<" 个数(以空格隔开,按回车结束):";
59 for(int i=0;i<n;i++){
60 p=new LNode; //生成新结点
61 cin>>p->data; //输入元素值
62 p->next=NULL;
63 r->next=p; //插入到表尾
64 r=p; //r指向新的尾结点 r始终指向当前节点
65 }
66 }//CreateList_L
67
68 Status findValList_L(LinkList L,int i,ElemType &indexVal){ //5.查找位序为i的元素,返回其值
69 LinkList p=L->next;//指向第一个结点
70 int j=1;
71 while(p && j<i){ //找第i个节点
72 p=p->next;
73 ++j;
74 }
75 if(!p||j>i)return ERROR;//i值不合法i大于表长或者是i小于1
76 indexVal=p->data;
77 return OK;
78 }
79
80 Status findIndexList_L(LinkList L,ElemType val,int &index){ //6.依值查找,返回其位序
81 LinkList p=L->next;//指向第一个节点
82 int j=1;
83 while(p){
84 if(p->data==val){
85 index=j;
86 return OK;
87 }
88 p=p->next;
89 j++;
90 }
91 return ERROR;
92 }
93
94 Status deleteIndexList_L(LinkList &L,int i){ //7.删除表中第i个元素
95 int j=0;
96 LinkList p=L; //这时要指向头节点,因为当i=1时,下面的循环进不去,也就是if判断不成功,进行删除节点操作
97 while(p && j<i-1){ //指向第i-1个节点
98 p=p->next;
99 j++;
100 }
101 if(!p||j>i-1)return ERROR;//如果p是空的话也就代表i大于表长,或者是
102 LinkList q=p->next;//q节点指向第i个节点
103 if(!q)return ERROR; //根据条件,此处应该判断p的后继是否为空即为i这个特殊情况,举个例子,表长为3时,i为4,到此句的时候就成立,表示表长加1这个位置没有元素
104 p->next=q->next;//链接链表
105 delete q;
106 return OK;
107 }
108
109 Status findMaxList_L(LinkList L,int &index,int &MaxVal){ //8.返回值最大的元素及其在表中位置,引用最大值
110 if(L->next==NULL)return ERROR;//如果是空链表,则返回0
111 LinkList p=L->next->next;//将p指向第二个节点
112 int j=2;//同时同步指针位置
113 MaxVal=L->next->data;//标记第一个节点的值为最大值
114 index=1;//同步最大值的位置
115 while(p){
116 if(p->data>MaxVal){
117 MaxVal=p->data;
118 index=j;
119 }
120 p=p->next;
121 j++;
122 }
123 return OK;
124 }
125
126 Status reverseList_L(LinkList &L){ //9.就地逆置算法
127 LinkList p=L->next,q; //先用p来保存原来的第一个节点
128 L->next=NULL;//仍利用原表的空间,此时将头结点指向空
129 if(!p)return ERROR;
130 while(p){
131 q=p->next;//先用q来保存p节点的next域,用来移动原来的链表
132 p->next=L->next; //仍用L空间,使用插在头结点后面的位置也就是前插法
133 L->next=p; //L(带头节点)时刻指向当前节点p
134 p=q; //将p重新指向原表中后继
135 }
136 return OK;
137 }
138
139 Status delItemList_L(LinkList &L,ElemType item){ //10.删除表中所有值为item的数据元素
140 LinkList p=L,q;//指向头节点,临时指针q
141 bool f=false;//标记链表中是否有item这个元素
142 while(p){
143 if((q=p->next)&&(q->data==item)){ //先判断是否有这个p->next这个元素
144 if(!f)f=true;//有的话只标记一次就好
145 p->next=q->next; //链接链表
146 delete q;
147 }
148 else p=p->next;//否则才移动p
149 }
150 if(!f)return ERROR; //标记该表中没有此元素
151 return OK;
152 }
153
154 int main()
155 {
156 int i,n,choose;
157 ElemType x;
158 LinkList L,p;
159
160 choose=-1;
161 while(choose!=0)
162 {
163 cout<<"******************************************************************************\n";
164 cout<<" 1. 建立空链表; 2. 在表中输入指定个数的数据元素\n";
165 cout<<" 3. 在第i个元素的前插入一个元素; 4. 逐个显示表中数据元素\n";
166 cout<<" 5. 查找位序为i的元素,返回其值; 6. 依值查找,返回其位序\n";
167 cout<<" 7. 删除表中第i个元素; 8. 返回值最大的元素及其在表中位置\n";
168 cout<<" 9. 就地逆置; 10. 删除表中所有值为item的数据元素\n";
169 cout<<" 0. 退出\n";
170 cout<<"*******************************************************************************\n";
171
172 cout<<"请选择:";
173 cin>>choose;
174 switch(choose)
175 {
176 case 1: //建立一个单链表
177 if(InitList_L(L))
178 cout<<"成功建立链表!\n\n";
179 break;
180 case 2: //使用后插法创建单链表
181 cout<<"请输入一个数,代表元素的个数:";
182 cin>>n;
183 CreateList_L(L,n);
184 cout<<"成功创建链表!\n\n";
185 break;
186 case 3: //单链表的插入
187 cout<<"请输入两个数,分别代表插入的位置和插入数值(用空格间隔,最后回车):";
188 cin>>i>>x; //输入i和x,i代表插入的位置,x代表插入的数值
189 if(ListInsert_L(L,i,x))
190 cout<<"成功将"<<x<<"插在第"<<i<<"个位置\n\n";
191 else
192 cout<<"插入失败!\n\n";
193 break;
194 case 4: //单链表的输出
195 p=L->next;//指向第一个节点
196 if(!p)
197 cout<<"当前为空链表"<<endl<<endl;
198 else{
199 cout<<"现在链表里的数分别是:";
200 i=0;
201 while(p){//循环直到为空
202 i++;
203 cout<<p->data<<",";
204 p=p->next;
205 }
206 cout<<"共有"<<i<<"个元素。"<<endl<<endl;
207 }
208 break;
209 case 5: //查找位序为i的元素,返回其值
210 cout<<"请输入一个你想要查找该元素的位序:";
211 cin>>i;
212 if(findValList_L(L,i,x))
213 cout<<"位序为"<<i<<"的元素为"<<x<<".\n"<<endl;
214 else
215 cout<<"输入位序序号不在链表节点序号范围内"<<endl<<endl;
216 break;
217 case 6: //依值查找,返回其位序
218 int index;
219 cout<<"请输入要查找的元素:";
220 cin>>x;
221 if(findIndexList_L(L,x,index))
222 cout<<"查找元素"<<x<<"在链表中的位序为"<<index<<".\n"<<endl;
223 else
224 cout<<"此元素不在该链表中"<<endl<<endl;
225 break;
226 case 7: //删除表中第i个元素
227 cout<<"请输入删除表中元素的位置:";
228 cin>>i;
229 if(deleteIndexList_L(L,i))
230 cout<<"第"<<i<<"个位置的元素已被删除.\n"<<endl;
231 else
232 cout<<"输入位置不在当前链表节点序号范围内"<<endl<<endl;
233 break;
234 case 8: //返回值最大的元素及其在表中位置
235 ElemType MaxVal;
236 if(findMaxList_L(L,i,MaxVal))
237 cout<<"当前链表中最大的元素为"<<MaxVal<<",其位置为"<<i<<".\n"<<endl;
238 else
239 cout<<"当前为空链表"<<endl<<endl;
240 break;
241 case 9: //就地逆置
242 if(reverseList_L(L))
243 cout<<"就地成功逆置链表"<<endl<<endl;
244 else
245 cout<<"此表为空链表"<<endl<<endl;
246
247 break;
248 case 10: //删除表中所有值为item的数据元素
249 if(L->next==NULL)
250 cout<<"当前为空链表"<<endl<<endl;
251 else{
252 cout<<"请输入要删除链表的一个元素:";
253 cin>>x;
254 if(delItemList_L(L,x))
255 cout<<"删除成功,已经将元素"<<x<<"从链表中删除.\n"<<endl;
256 else
257 cout<<"此链表没有"<<x<<"这个元素.\n"<<endl;
258 }
259 break;
260 }
261 }
262 return 0;
263 }
原文:https://www.cnblogs.com/acgoto/p/8673398.html