c++递归的实例使用1(链表和排序二叉树)——包含单链表的倒序输出和排序二叉树的后序输出 #朱小黑的小白日记#

过程封装一部分比较实用的单链表函数
主要练习的是其中的 void reverse_print_list函数,需要使用简单的递归,在二叉树中的递归会更加复杂一些。

/*goodlist.h*/
#include<iostream> 
using namespace std;
struct Node {
 int value;
 Node* next;
};
int list_tail_insert(Node* list_head, int var);//单个数据插入,尾插法
Node* list_head_insert(Node* list_head, int var);//单个数据插入,头插法
Node* list_specific_insert(Node* list_head, int location, int var);//指定位置插入,可以插入头,尾,或者头尾之间任意位置
void print_list(Node* list_head);//输出链表,循环方式,空格隔开
void reverse_print_list(Node* list_head);//逆序输出,递归方式,空格隔开
//void reverseprintlist(Node* list_head);
void change_specific_var(Node* list_head, int old_var, int new_var);//修改链表中的指定元素值
Node* del_specific_var(Node* list_head, int del_var);//删除链表中的指定元素值
Node* sort(Node* list_head);//从小到大排序
int list_len(Node* list_head);//检测链表长度

以下是自定义这些链表函数内容(一开始为了快点交作业排序采用了交换值的方法,之后会改为交换节点,方便以后的复用)

Node* list_head_insert(Node* list_head, int var) {
 Node* p = new Node;
 p->value = var;
 p->next = NULL;
 if (list_head == NULL)return p;
 else {
  p->next = list_head;
  return p;
 }
}
int list_tail_insert(Node* list_head, int var) {
 if (list_head == NULL) {
  cout << "无法在空链表中插入尾部" << endl;
  exit(-1);
 }
 else
 {
  Node* p = new Node;
  p->value = var;
  p->next = NULL;
  Node* tmp = list_head;
  while (tmp->next) tmp = tmp->next;
  tmp->next = p;
  return 1;
 }
}
Node* sort(Node* list_head){
if (list_head == NULL || list_head->next == NULL) return list_head;//如果链表为空或只有一个节点,直接返回
 int len = list_len(list_head);
 Node* p = list_head;
 for (int i = 1;i <= len - 1;++i) {
  p = list_head;
  while (p->next) {
   if (p->value > p->next->value) {
    int tmp = p->value;
    p->value = p->next->value;
    p->next->value = tmp;
   }
   p = p->next;
  }
 }
 return list_head;
}

其他比较简单的函数在此不再列出,来到关键的单链表倒序输出

void reverse_print_list(Node* list_head) {
 static int i = 0;//设置标识符用来判断是否应该输出换行符
 ++i;
 if (list_head == NULL) {
  --i;
  return;
 }
 else reverse_print_list(list_head->next);
 cout << list_head->value << " ";
 --i;
 if (i == 0)cout << endl;
}

最初没有static int作为标识符,没有办法在打印完链表后输出一个回车,所以我采用的办法是在另一个函数中包含这个递归函数,结束后再输出一个回车。

虽然这样十分的简单粗暴,效果也很好,但破坏了过程的封装,使用者还可以调用单独的递归函数(主要是觉得这样写很难看)然后再一位同学的启发下改用静态变量来控制递归函数,也是将来使用递归的一个重要的小技巧。

顺便练习节点交换的冒泡排序

Node* sort(Node* list_head){
if (list_head == NULL || list_head->next == NULL) return list_head;
 int len = list_len(list_head);
 Node* cur = list_head, * pre = list_head;
 for (int i = 1;i <= len - 1;++i) {
  cur = list_head;
  pre = list_head;
  while (cur->next) {
   if (cur->value > cur->next->value) {
    if (cur == list_head) {
     list_head = list_head->next;
     cur->next = list_head->next;
     list_head->next = cur;
     pre = list_head;
     continue;
    }
    else {
     pre->next = cur->next;
     cur->next = NULL;
     cur->next = pre->next->next;
     pre->next->next = cur;
     pre = pre->next;
     continue;
    }
   }
   pre = cur;
   cur = cur->next;
  }
 }
 return list_head;

}

————————————————————————————————————
二叉树

#include<iostream>
using namespace std;
struct Node {
 int value;
 Node* leftnext;
 Node* rightnext;
};
bool is_leaf(Node* head);//是否是叶子结点
Node* insert(Node* T, int x);//在二叉树中插入一个结点
void postorder(Node* T);//后序遍历
Node* insert(Node* T, int x) {
 Node* p = new Node;
 p->value = x;
 p->leftnext = NULL;
 p->rightnext = NULL;
 if (!T) return p;
 Node* temp = T;
 while (temp) {
  if (x < temp->value)
  {
   if (temp->leftnext == NULL) {
    temp->leftnext = p;
    return T;
   }
   else {
    temp = temp->leftnext;
    continue;
   }
  }
  else
  {
   if (temp->rightnext == NULL) {
    temp->rightnext = p;
    return T;
   }
   else {
    temp = temp->rightnext;
    continue;
   }
  }
 }
 exit(-1);
}
bool is_leaf(Node* head) {
 if (head->leftnext == NULL && head->rightnext == NULL) return true;
 else return false;
}
void postorder(Node* T){
if (T == NULL) return;
 else if (is_leaf(T)) {
  cout << T->value << " ";
  return;
 }
 if (T->leftnext != NULL) {
  postorder(T->leftnext);
  if(T->rightnext==NULL) cout << T->value << " ";
 }
 if (T->rightnext != NULL) {
  postorder(T->rightnext);
  cout << T->value<<" ";
 }
 return;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值