《数据结构教程》(李春葆 主编)课后习题【练习题5】
【5.1】
1 #include <stdio.h>
2 #define MAXSIZE 1000
3 double GetAve(int a[],int n) //求数组a[]前n个数的平均数
4 {
5 if(n==1)
6 return a[1];
7 return (a[n]+GetAve(a,n-1)*(n-1))/n;
8 }
9 void Input(int a[],int n) //输入数据
10 {
11 int i;
12 for(i=1;i<=n;i++)
13 scanf("%d",&a[i]);
14 }
15 int main()
16 {
17 int n;
18 int a[MAXSIZE+1];
19 printf("请输入n:\n");
20 while(scanf("%d",&n)!=EOF){
21 if(n==0) break;
22 printf("请输入n个数:\n");
23 Input(a,n);
24 printf("这n个数的平均数为:\n");
25 printf("%.2lf\n",GetAve(a,n));
26 printf("\n");
27 printf("请输入n:\n");
28 }
29 return 0;
30 }
【5.2】
1 #include <stdio.h>
2 #include <malloc.h>
3 #include <stdlib.h>
4
5 #define MAXSIZE 1000
6 typedef int ElemType;
7 typedef struct node{ //定义链表节点类型
8 ElemType data;
9 struct node * next;
10 } Node;
11 typedef Node *LinkedNode;
12
13 /*[1] 求以h为头指针的单链表的节点个数 */
14 int GetNodeNum(LinkedNode &h)
15 {
16 if(h==NULL)
17 return 0;
18 else
19 return GetNodeNum(h->next) + 1;
20 }
21 /*[2] 正向显示以h为头指针的单链表的所有节点值 */
22 void PrintForward(LinkedNode &h)
23 {
24 if(h==NULL) //链表到头,结束输出
25 return ;
26 printf("%d ",h->data);
27 PrintForward(h->next); //输出下一个元素值
28 }
29 /*[3] 反向显示以h为头指针的单链表的所有节点值 */
30 void PrintReverse(LinkedNode &h)
31 {
32 if(h==NULL)
33 return ;
34 PrintReverse(h->next); //链表跑到头,再开始输出
35 printf("%d ",h->data);
36 }
37 /*[4] 删除以h为头指针的单链表中值为x的第一个节点 */
38 bool DeleteFirstX(LinkedNode &h,ElemType x)
39 {
40 //递归出口
41 if(h==NULL)
42 return false;
43 else if(h->data==x){ //第一个节点就是要找的节点,删除
44 if(h->next==NULL){ //只有一个节点
45 free(h);
46 h = NULL;
47 return true;
48 }
49 LinkedNode p;
50 p = h;
51 h = h->next;
52 free(p);
53 return true;
54 }
55 else if(h->next!=NULL){
56 if(h->next->data==x){ //找到节点,删除
57 LinkedNode p;
58 p = h->next;
59 h->next = p->next;
60 free(p);
61 return true;
62 }
63 }
64 //递归体
65 if(DeleteFirstX(h->next,x))
66 return true;
67 else
68 return false;
69 }
70 /*[5] 删除以h为头指针的单链表中值为x的所有节点 */
71 void DeleteAllX(LinkedNode &h,ElemType x)
72 {
73 if(h==NULL)
74 return ;
75 if(h->data==x){ //第一个节点就是要找的节点,删除
76 if(h->next==NULL){ //只有一个节点
77 free(h);
78 h = NULL;
79 return ;
80 }
81 LinkedNode p;
82 p = h;
83 h = h->next;
84 free(p);
85 DeleteAllX(h,x);
86 }
87 else if(h->next==NULL) //递归出口
88 return ;
89 else if(h->next->data==x){ //找到节点,删除
90 LinkedNode p;
91 p = h->next;
92 h->next = p->next;
93 free(p);
94 DeleteAllX(h,x);
95 }
96 else
97 DeleteAllX(h->next,x);
98 }
99
100 /*[6] 删除以h为头指针的单链表中最大节点值 */
101 void DeleteMaxNode(LinkedNode &h,LinkedNode c,LinkedNode p)
102 {
103 if(h==NULL)
104 return ;
105 if(c->next==NULL){ //到头,开始删除
106 if(p->next ==NULL){
107 free(p);
108 h = NULL;
109 return ;
110 }
111 if(p==h && p->data > p->next->data){ //第一个节点是要删除的节点
112 h = h->next;
113 free(p);
114 return ;
115 }
116 else{
117 LinkedNode q = p->next;
118 p->next = q->next;
119 free(q);
120 return ;
121 }
122 }
123 if(c->next->data > p->next->data)
124 p = c;
125 DeleteMaxNode(h,c->next,p);
126 }
127 /*[7] 删除以h为头指针的单链表中最小节点值 */
128 void DeleteMinNode(LinkedNode &h,LinkedNode c,LinkedNode p)
129 {
130 if(h==NULL)
131 return ;
132 if(c->next==NULL){ //到头,开始删除
133 if(p->next ==NULL){
134 free(p);
135 h = NULL;
136 return ;
137 }
138 if(p==h && p->data < p->next->data){ //第一个节点是要删除的节点
139 h = h->next;
140 free(p);
141 return ;
142 }
143 else{
144 LinkedNode q = p->next;
145 p->next = q->next;
146 free(q);
147 return ;
148 }
149 }
150 if(c->next->data < p->next->data)
151 p = c;
152 DeleteMinNode(h,c->next,p);
153 }
154
155 /* 1. 初始化单链表 */
156 LinkedNode LinkedListInit()
157 {
158 LinkedNode head = (Node*)malloc(sizeof(Node));
159 head->next = NULL;
160 return head;
161 }
162
163 /* 2. 清空单链表 */
164 void LinkedListClear(LinkedNode &L)
165 {
166 //L为头指针
167 while(L){ //依次清空节点,直到头指针指向的下一个节点的地址为空
168 LinkedNode t;
169 t = L;
170 L = t->next;
171 free(t);
172 }
173 return ;
174 }
175
176 /* 3. 用尾插法建立单链表 */
177 LinkedNode LinkedListCreat( LinkedNode L,ElemType a[],int n ) //讲数组a中的元素以尾插法放入链表中
178 {
179 int i;
180 LinkedNode p = L;
181 p->data = a[1];
182 for(i=2;i<=n;i++){
183 LinkedNode q = (LinkedNode)malloc(sizeof(Node));
184 q->data = a[i];
185 q->next = NULL;
186 p->next = q;
187 p = q;
188 }
189 return L;
190 }
191
192 int Menu()
193 {
194 int in;
195 printf("[1] 重新建立一个链表\n");
196 printf("[2] 求以h为头指针的单链表的节点个数\n");
197 printf("[3] 正向显示以h为头指针的单链表的所有节点值\n");
198 printf("[4] 反向显示以h为头指针的单链表的所有节点值\n");
199 printf("[5] 删除以h为头指针的单链表中值为x的第一个节点\n");
200 printf("[6] 删除以h为头指针的单链表中值为x的所有节点\n");
201 printf("[7] 删除以h为头指针的单链表中最大节点值\n");
202 printf("[8] 删除以h为头指针的单链表中最小节点值\n");
203 printf("[0] 按其他键退出\n");
204 scanf("%d",&in);
205 return in;
206 }
207 LinkedNode Reply(LinkedNode head,int in)
208 {
209 int i,n,x;
210 int a[MAXSIZE+1];
211 switch(in){
212 case 1: //重新建立一个链表
213 LinkedListClear(head);
214 head = LinkedListInit();
215 printf("你要输入多少个数据?\n");
216 scanf("%d",&n); //输入链表大小
217 printf("请依次输入数据:\n");
218 for(i=1;i<=n;i++)
219 scanf("%d",&a[i]);
220 head = LinkedListCreat(head,a,n);
221 printf("链表建立成功!\n");
222 break;
223
224 case 2: //求以h为头指针的单链表的节点个数
225 printf("单链表的节点个数为:%d\n",GetNodeNum(head));
226 break;
227
228 case 3: //正向显示以h为头指针的单链表的所有节点值
229 printf("链表中元素依次为(正向):\n");
230 PrintForward(head);
231 printf("\n");
232 break;
233
234 case 4: //反向显示以h为头指针的单链表的所有节点值
235 printf("链表中元素依次为(反向):\n");
236 PrintReverse(head);
237 printf("\n");
238 break;
239
240 case 5: //删除以h为头指针的单链表中值为x的第一个节点
241 printf("输入你要删除的元素的值?\n");
242 scanf("%d",&x);
243 if(DeleteFirstX(head,x))
244 printf("删除成功!\n");
245 else
246 printf("删除失败!\n");
247 printf("链表中元素依次为(正向):\n");
248 PrintForward(head);
249 printf("\n");
250 break;
251
252 case 6: //删除以h为头指针的单链表中值为x的所有节点
253 printf("输入你要删除的元素的值?\n");
254 scanf("%d",&x);
255 n = GetNodeNum(head);
256 DeleteAllX(head,x);
257 i = GetNodeNum(head);
258 if(n!=i)
259 printf("删除成功!\n");
260 else
261 printf("删除失败!\n");
262 printf("链表中元素依次为(正向):\n");
263 PrintForward(head);
264 printf("\n");
265 break;
266
267 case 7: //删除以h为头指针的单链表中最大节点值
268 n = GetNodeNum(head);
269 DeleteMaxNode(head,head,head);
270 i = GetNodeNum(head);
271 if(n!=i)
272 printf("删除成功!\n");
273 else
274 printf("删除失败!\n");
275 printf("链表中元素依次为(正向):\n");
276 PrintForward(head);
277 printf("\n");
278 break;
279
280 case 8: //删除以h为头指针的单链表中最小节点值
281 n = GetNodeNum(head);
282 DeleteMinNode(head,head,head);
283 i = GetNodeNum(head);
284 if(n!=i)
285 printf("删除成功!\n");
286 else
287 printf("删除失败!\n");
288 printf("链表中元素依次为(正向):\n");
289 PrintForward(head);
290 printf("\n");
291 break;
292
293 default:
294 printf("Bye~\n");
295 exit(1);
296 }
297 system("pause");
298 system("cls");
299 return head;
300 }
301 int main()
302 {
303 int in; //存储输入命令
304 LinkedNode head = NULL;
305 while(1){
306 in = Menu();
307 head = Reply(head,in); //响应命令
308 }
309 return 0;
310 }
Freecode : www.cnblogs.com/yym2013