java单链表 递归求平均值_递归实现单链表的各种基本操作

1 #include

2 #include

3 using namespacestd;4

5 #define OK 1

6 #define ERROR 0

7 typedef intStatus;8

9 typedef structLNode10 {11 int data; //结点的数据域

12 struct LNode *next; //结点的指针域

13 }LNode, *LinkList; //LinkList为指向结构体LNode的指针类型

14

15 void create_List(LinkList &L, int n){ //法1:递归初始化创建n个节点

16 if (n == 0)return;//创建n个节点

17 else{ //此时传进来的是第一个节点的指针

18 L = new LNode; //指针指向新生成的节点

19 cin >> L->data; //输入数据,将其压栈

20 L->next = NULL; //尾插法,先将下一个指针域赋为NULL

21 create_List(L->next, n - 1); //递归创建n个节点

22 }23 }24

25 Status Creat_LinkList(LinkList &L){ //法2:创建链表,当输入数字为-1时,令当前指针为空

26 intnum;27 cout << "请每行输入一个数据元素并按回车(直到-1退出):";28 cin >> num;//输入数据

29 if (num == -1){ L = NULL; return OK; } //结束

30 else{31 L = new LNode; //申请新的节点,指针指向结构体

32 L->data = num; //先将数据放到数据域

33 return Creat_LinkList(L->next); //递归创建节点

34 }35 }36

37 int count_LNode(LinkList L){ //统计节点个数,传入链表首地址

38 if (L == NULL)return 0; //递归结束条件,递归到尾节点的下一个节点,直接返回

39 else return count_LNode(L->next) + 1; //否则继续指向下一个节点,表长加1

40 }41

42 void lprint_LNode(LinkList L){ //正序打印链表

43 if (L == NULL)return; //递归的结束条件

44 else{45 cout << L->data << ' '; //先打印当前节点的数据

46 lprint_LNode(L->next); //再递归循环链表

47 }48 }49

50 void bprint_LNode(LinkList L){ //反序打印链表

51 if (L == NULL)return; //递归的结束条件

52 else{53 bprint_LNode(L->next); //先递归循环链表,将数据域压入栈中

54 cout << L->data << ' '; //讲数据出栈并打印

55 }56 }57

58 int maxVal_List(LinkList L) //求表中元素的最大值

59 {60 intmaxVal;61 if (L->next == NULL) //如果到尾节点,就把当前节点的值赋值为maxVal

62 return L->data; //递归结束条件,出栈比较

63 else{64 maxVal = maxVal_List(L->next);//先把一个个数据压栈

65 if (L->data >maxVal)66 maxVal = L->data;67 returnmaxVal;68 }69

70 }71

72 int minVal_List(LinkList L) //求表中元素的最小值

73 {74 intminVal;75 if (L->next == NULL) //如果到尾节点,就把当前节点的值赋值为minVal

76 return L->data; //返回末尾的值赋给尾节点

77 else{78 minVal = minVal_List(L->next);//先把一个个数据压栈

79 if (L->data data;81 return minVal; //返回上一层

82 }83 }84

85 int getSum_List(LinkList L){ //递归求该表中所有元素的和

86 if (L == NULL)return 0; //递归结束条件:当p指向空时,返回0

87 else //否则将当前指针指向的数据域压入栈中,递归到链表尾

88 return getSum_List(L->next) + L->data;89 }90

91 bool found = false;92 void Print_List(LinkList L, int val){ //12.打印单链表中从某节点元素开始后的所有节点

93 if (!L)return; //递归结束条件

94 else{95 if (L->data == val)found = true;96 if (found)cout << L->data << ' '; //只要从满足那一节点之后,打印该点之后的所有节点

97 Print_List(L->next, val); //递归

98 }99 }100

101 bool flag = false;//用来标记是否查找成功

102 void PriorElem_List(LinkList L, int val, int &preVal){ //9.求某元素的前驱元素,引用前驱元素

103 if (!L || L->data == val){ //当输入val刚好是第一个节点的时候,直接返回

104 preVal =val;105 return;106 }107 else{108 if (L->next && L->next->data == val){//找到值为val的前驱节点

109 preVal = L->data;110 flag = true;111 }112 else

113 PriorElem_List(L->next, val, preVal);//递归查找

114 }115 }116

117 LinkList pre =NULL;118 Status IsOrder_List(LinkList L){ //10.判断单链表是否递增有序

119 if (!L)return OK; //当遍历到尾节点的下一个位置,返回正确,表示递增有序

120 if (pre && (pre->data > L->data))returnERROR;121 pre = L; //将当前节点作为前驱pre节点

122 return IsOrder_List(L->next); //递归遍历每个节点

123 }124

125 int j = 1; //记录节点的序号

126 bool flag_insert = false;//标记是否插入成功

127 void insert_List(LinkList &L, int i, int e){ //11.在单链表的第i个位置插入元素e

128 LinkList q;129 if (i == 1){130 q = newLNode;131 q->data = e;//赋值

132 q->next =L;133 L = q;//L时刻指向尾节点

134 flag_insert = true;135 }136 if (!L || flag_insert)return; //递归终止条件

137 else{138 if (j == i - 1){139 q = new LNode; //申请一个新的节点

140 q->data = e; //接下来的操作按常规来

141 q->next = L->next;142 L->next =q;143 flag_insert = true;//表示插入成功

144 }145 else{146 j++; //表长先加1,再递归循环链表

147 insert_List(L->next, i, e);148 }149 }150 }151

152 bool findVal_list = false;153 void check_List(LinkList L, int val){ //检查val元素是否在表中

154 if (L == NULL || findVal_list)return; //递归出口,若找到的话就不用递归了

155 else{156 if (L->data == val)findVal_list = true; //此时已经找到

157 else check_List(L->next, val); //继续递归查找

158 }159 }160

161 int k = 1;162 bool delNodeflag = false;163 void delNode_List(LinkList &L, int i, int &e){ //13.删除单链表的第i个元素

164 if (!L || delNodeflag)return;165 else{166 LinkList q;167 if (i == 1){168 q =L;169 e = q->data;170 L = L->next;171 deleteq;172 delNodeflag = true;173 }174 else if (k == i - 1){ //找到要删除节点的前驱

175 q = L->next; //基本操作

176 e = q->data;177 L->next = q->next;178 deleteq;179 delNodeflag = true; //标记删除成功

180 }181 else{182 k++; //循环链表

183 delNode_List(L->next, i, e); //递归链表

184 }185 }186 }187

188

189 int i = 0; double sum = 0.0; //尾递归计算平均值190 //double getAverage_List(LinkList L){191 //if (L == NULL)return sum / i;192 //else{193 //sum += L->data;194 //i++;195 //return getAverage_List(L->next);196 //}197 //}

198 double getAverage_List(LinkList L,int n){//递归计算平均值

199 if (!L->next)return L->data;200 else{201 double ave = getAverage_List(L->next, n - 1);202 return (ave*(n - 1) + L->data) /n;203 }204 }205 intmain()206 {207 inte;208 intchoose;209

210 LinkList L;211 choose = -1;212 while (choose != 0)213 {214 cout << "******************************************************************************\n";215 cout << "1. 建立空链表(不带头节点); 2. 输入指定个数的数据元素创建链表\n";216 cout << "3. 正序打印表中元素 ; 4. 逆序打印表中元素\n";217 cout << "5. 求表中元素的最大值; 6. 求表中元素的最小值\n";218 cout << "7. 返回单链表的长度; 8. 递归求该表中所有节点元素的和\n";219 cout << "9. 查找某元素的前驱元素; 10.判断单链表是否递增有序 \n";220 cout << "11.在单链表的第i个位置插入元素e 12.打印单链表中从某节点元素开始后的所有节点\n";221 cout << "13.删除单链表的第i个元素 14.求表所有元素的平均值 \n";222 cout << "0. 退出\n";223 cout << "*******************************************************************************\n";224

225 cout << "请选择:";226 cin >>choose;227 switch(choose)228 {229 case 1: //建立空链表

230 L = NULL;//这里不带头结点,建立空链表

231 cout << "成功建立空链表" << endl <

234 /*cout << "请输入一个数,代表元素的个数:";235 cin >> i;236 if (i == 0)237 cout << "此时创建的是空链表" << endl<

243 if (Creat_LinkList(L)) //也可以用第2中创建节点的方法创建单链表,此时实参传入第一个节点的指针

244 cout << "成功创建单链表" <

246 cout << "创建单链表失败" <

249 if(count_LNode(L)){250 cout << "当前表中一共有" << count_LNode(L) << "个元素,正序输出依次为";251 lprint_LNode(L);252 cout << endl <

255 cout << "当前为空链表" << endl <

258 if(count_LNode(L)){259 cout << "当前表中一共有" << count_LNode(L) << "个元素,逆序输出依次为";260 bprint_LNode(L);261 cout << endl <

264 cout << "当前为空链表" << endl <

267 if(count_LNode(L)){268 cout << "表中最大的元素为:" << maxVal_List(L) << "。\n" <

271 cout << "当前为空链表" << endl <

274 if(count_LNode(L)){275 cout << "表中最小的元素为:" << minVal_List(L) << "。\n" <

278 cout << "当前为空链表" << endl <

281 if(count_LNode(L))282 cout << "当前单链表表长为" << count_LNode(L) << "。\n" <

284 cout << "当前为空表" << endl <

287 if(count_LNode(L))288 cout << "当前表中所有元素的和为" << getSum_List(L) << "。\n" <

290 cout << "当前为空表" << endl <

293 if (!L)294 cout << "当前为空表" << endl <>val;299 flag = false;300 PriorElem_List(L, val, preVal);301 if(flag)302 cout << "待查找元素" << val << "的前驱元素为" << preVal << "。\n" <

304 cout << "找不到" << val << "的前驱元素" << endl <

308 if(IsOrder_List(L))309 cout << "该链表递增有序" << endl <

311 cout << "该链表非递增" << endl <

314 cout << "请输入要插入元素的位置及插入的元素分别为(用空格隔开):";315 cin >> i >>e;316 if (i<1 || (i>count_LNode(L) + 1))317 cout << "输入" << i << "不在节点位置范围内。" << endl <

324 cout << "插入失败" << endl <

328 if (!L)329 cout << "当前为空表" << endl <>val;335 check_List(L, val);336 if(findVal_list){337 cout << "链表元素依次为:";338 Print_List(L, val);339 cout << endl <

342 cout << "该表中没有" << val << "这个元素。" << endl <

346 if (!L)347 cout << "当前链表为空。" << endl <>i;351 if (i<1 || i>count_LNode(L))352 cout << "输入" << i << "不在节点位置范围内。" << endl <

359 cout << "删除失败。" << endl <next ==NULL)365 cout << "当前链表为空" << endl <

368 int n =count_LNode(L);369 cout << "此时表中元素总和的平均值是";370 cout << setiosflags(ios::fixed) << setprecision(2) << getAverage_List(L,n) << endl <

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值