- 用函数实现平衡二叉排序树算法(1)插入新结点;(2)前序、中序、后序遍历二叉树 (递归);(3)前序、中序、后序遍历的非递归算法 ;(4)层次遍历二叉树 ;(5)在二叉树中查找给定关键字;(6)交换各结点的左右子树 ;(7)求二叉树的深度 ;(8)求叶子结点数;(9)删除某结点。
-
#include <iostream> #include <stack> #include <queue> #include <algorithm> using namespace std; int flag = 0,n=0; typedef struct n//data为节点数据,lchild和rchild分别为左子树和右子树 { int data; struct n* lchild, * rchild; }Tree, * PTree;//定义 int GetHeight(PTree& T)//二叉树的高度 { if (!T) return 0; return max(GetHeight(T->lchild), GetHeight(T->rchild)) + 1;//左右子树中较大者加一 } PTree zuoxuan(PTree& T)//对树进行调整,插入右孩子的右子树,左旋 { PTree a = T->rchild; T->rchild = a->lchild; a->lchild = T; return a; } PTree youxuan(PTree& T)//对树进行调整,插入左孩子的左子树,右旋 { PTree a = T->lchild; T->lchild = a->rchild; a->rchild = T; return a; } PTree zuoyou(PTree& T)//对树进行调整,先左旋再右旋 { PTree a = T; if (!a->rchild) { a = youxuan(a); return a; } a->lchild = zuoxuan(a->lchild); a = youxuan(a); return a; } PTree youzuo(PTree& T)//对树进行调整,先右旋再左旋 { PTree a = T; if (!a->lchild) { a = zuoxuan(a); return a; } a->rchild = youxuan(a->rchild); a = zuoxuan(a); return a; } void ist(int a, PTree& T)//插入数据 { int i, j; if (!T) { T = new Tree; T->data = a; T->lchild = NULL; T->rchild = NULL; } else if (a > T->data) { ist(a, T->rchild); if (GetHeight(T->rchild) - GetHeight(T->lchild) > 1)//判断是否需要调整 { if (a > T->rchild->data) { T = zuoxuan(T); } else { T = youzuo(T); } } } else { ist(a, T->lchild); if (GetHeight(T->lchild) - GetHeight(T->rchild) > 1)//判断是否需要调整 { if (a < T->lchild->data) { T = youxuan(T); } else { T = zuoyou(T); } } } } void cret(int n, PTree& T)//创建二叉树 { int a, i; for (i = 0; i < n; i++) { scanf("%d", &a); ist(a, T); } } void PreOrder(PTree& T)//前序遍历递归算法 { if (T) { printf("%d ", T->data); PreOrder(T->lchild); PreOrder(T->rchild); } } void InOrder1(PTree& T)//中序遍历递归算法 { if (T) { InOrder1(T->lchild); printf("%d ", T->data); InOrder1(T->rchild); } } void LastOrder(PTree& T)//后序遍历递归算法 { if (T) { LastOrder(T->lchild); LastOrder(T->rchild); printf("%d ", T->data); } } void Traverse(PTree& T)//三种次序遍历 { PreOrder(T); printf("\n"); InOrder1(T); printf("\n"); LastOrder(T); printf("\n"); } void srch(int a, PTree& T)//查找关键字 { if (!T) { flag = 0; return; } if (a == T->data) { flag = 1; return; } else if (a < T->data) { srch(a, T->lchild); } else { srch(a, T->rchild); } } void ExchangeTree(PTree& T)//交换左右子树 (递归实现) { if (!T) return; swap(T->lchild, T->rchild); ExchangeTree(T->lchild); ExchangeTree(T->rchild); } int GetNum(PTree& T)//叶子节点的数量 { if (!T) return 0; if (!T->lchild && !T->rchild) return 1; return GetNum(T->lchild) + GetNum(T->rchild);//左右子树的叶子节点 } void InOrder2(PTree& T)//非递归中序遍历 { if (!T) { return; } int i, t; stack<PTree> s; PTree p = T; while (p || !s.empty()) { while (p) { s.push(p); p = p->lchild; } if (!s.empty()) { p = s.top(); s.pop(); printf("%d ", p->data); p = p->rchild; } } } void PreOrder2(PTree& T)//非递归前序遍历 { if (!T) { return; } int i, t; stack<PTree> s; PTree p = T; s.push(T); while (!s.empty()) { p = s.top(); s.pop(); printf("%d ", p->data); if (p->rchild != NULL) { s.push(p->rchild); } if (p->lchild != NULL) { s.push(p->lchild); } } } void LastOrder2(PTree& T)//非递归后序遍历 { if (!T) { return; } int i, t; stack<PTree> s; PTree p = T,q=NULL; while (p!=NULL||!s.empty()) { while (p != NULL) { s.push(p); p = p->lchild; } p = s.top(); s.pop(); if (p->rchild == NULL || p->rchild == q) { q = p; printf("%d ", p->data); p = NULL; } else { s.push(p); p = p->rchild; } } } void Traverse2(PTree& T)//三种非递归遍历 { PreOrder2(T); printf("\n"); InOrder2(T); printf("\n"); LastOrder2(T); printf("\n"); } void Breadother(PTree& T)//层序遍历 { PTree p = T; queue<PTree> s; if (!T) { return; } s.push(p); while (!s.empty()) { p = s.front(); printf("%d ", p->data); if (p->lchild) { s.push(p->lchild); } if (p->rchild) { s.push(p->rchild); } s.pop(); } } PTree min(PTree& T)//删除操作辅助函数,找到最小的结点 { if (T == NULL) return NULL; while (T->lchild) T=T->lchild; return T; } int dele(PTree& T, int a) { if (!T) { return 0; } if (a < T->data) { dele(T->lchild, a);//递归找到要删除结点 if (GetHeight(T->rchild) - GetHeight(T->lchild) > 1)//检测并调整树的平衡性 { if (a < T->rchild->data) T = youzuo(T); else T = zuoxuan(T); } } else if (a > T->data) { dele(T->rchild, a);//递归找到要删除结点 if (GetHeight(T->lchild) - GetHeight(T->rchild) > 1)//检测并调整树的平衡性 { if (a < T->lchild->data) T = youxuan(T); else T = zuoyou(T); } } else if (T->lchild && T->rchild)//待删除结点有左右孩子 { flag = 1; PTree p = min(T->rchild); T->data = p->data; dele(T->rchild, p->data); } else if (T->lchild)//只有一个孩子或者没有孩子 { flag = 1; T = T->lchild; } else { flag = 1; T = T->rchild; } return 1; } int main() { int a, b, c,d,l,k; int i = 0,j=0; PTree T = NULL;//创建一个AVL树 printf("请输入树的结点数:"); scanf("%d", &n); cret(n, T); printf("\n三种遍历(递归):\n"); Traverse(T); printf("\n三种遍历(非递归):\n"); Traverse2(T); printf("请输入要查找的数据:"); scanf("%d",&a); srch(a, T); printf("%d\n", flag); flag = 0; printf("请输入要查找的数据:"); scanf("%d", &b); srch(b, T); printf("%d\n", flag); flag = 0; i = 1; while (i) { printf("请输入要插入的数据:"); scanf("%d", &c); ist(c, T); printf("\n三种遍历:\n"); Traverse(T); printf("如果要退出插入操作,请输入0,如要继续,请输入1:"); scanf("%d", &i); } printf("\n非递归中序遍历:\n"); InOrder2(T); printf("\n"); printf("层序遍历:\n"); Breadother(T); printf("\n"); printf("\n交换左右子树\n"); ExchangeTree(T); printf("\n三种遍历:\n"); Traverse(T); printf("\n交换左右子树\n"); ExchangeTree(T); printf("\n三种遍历:\n"); Traverse(T); printf("二叉树的深度:%d\n", GetHeight(T)); printf("二叉树的叶子结点个数:%d\n", GetNum(T)); i = 1; while (i) { printf("\n请输入要删除的数据:\n"); scanf("%d", &d); flag = 0; dele(T, d); if (flag) { printf("\n删除成功!"); } else { printf("\n删除失败!\n"); } printf("\n三种遍历:\n"); Traverse(T); printf("如果要退出删除操作,请输入0,如要继续,请输入1:"); scanf("%d", &i); } return 0; }