目录
1.或者为空二叉树,即n=0。
2.或者由一个根结点和两个互不相交的被称为根的左子树和右子树组成。左子树和右子树又分别是一颗二叉树。
特点:1.每个结点至多只有两棵子树。2.左右子树不能颠倒(二叉树是有序树)



1.只有最后一层有叶子结点。
2.不存在度为1的结点(结点的度要么为2,要么就是0)。
3.按层序从1开始编号,结点i的左孩子为2i,右孩子为2i+1;结点i的父结点为[i/2](i/2然后舍去小数取整)(如果有的话)

1.只有最后两层可能有叶子结点。
2.最多只有一个度为1的结点。
3.按层序从1开始编号,结点i的左孩子为2i,右孩子为2i + 1;结点i的父结点为[i / 2](i / 2然后舍去小数取整)(如果有的话)
完全二叉树:当且仅当其每个结点都与高度为h的满二叉树中编号为1到n的结点一一对应时,称为完全二叉树。
4.当i<=[n/2](取n/2的整数部分)为分支结点,i>[n/2]为叶子结点。

1.左子树上所有结点的关键字均小于根结点的关键字
2.右子树上所有结点的关键字均大于根结点的关键字
3.左子树和右子树又各是一棵二叉排序树
补充:二叉排序树可用于元素的排序、搜索

分析:假设树中结点总数为n,则
1.n = n0 + n1 + n2(树的结点数 = 度为0的结点数 + 度为1的结点数 + 度为2的结点数)
2.n = n1 + 2n2 + 1(树的结点数 = 总度数 + 1,其中度为0的结点数有n0个,度数和为0×n0;度为1的结点数有n1个,度数和为n1;度为2的结点数有n2个,度数和为2n2。所以总度数为n1 + 2n2)
由上面两式相等得到:n0 + n1 + n2 = n1 + 2n2 + 1,所以n0 = n2 + 1
分析:第一层有1个结点;第二层有2个结点;第三层有2^2个结点.....第h层有2^(h-1)个结点
总共有1+2+2^2......+2^(h-1)=(1-2^h)/(1-2)=2^h-1
分析:

分析:
完全二叉树最多只有一个度为1的结点,即n1=0或1
由于n0=n2+1,所以n0+n2=2n2+1一定是奇数
又推出若完全二叉树有2k个(偶数)个结点,则必有n1=1,n0=k,n2=k-1
若完全二叉树有2k-1个(奇数)个结点,则必有n1=0,n0=k,n2=k-1
按照一组地址连续的存储单元依次自上而下、自左至右存储完全二叉树上的结点元素

完全二叉树结点i的的左孩子是2i,右孩子是2i+1,父结点是[i/2](i/2后取整),所在层次是[log2(n+1)](2为底)


- //第一种
- typedef struct wqbtree
- {
- ElemType SBTree[MaxSize];//结点中的数据元素
- int n;//记录结点个数
- }Fbitree;
-
- //第二种
- typedef ElemType SBTree[MaxSize];

二叉树中每一个结点用链表中的一个结点来存储,结构结点如上图。
其中data表示值域,用于存储对应的数据元素;lchild和rchild分别表示左指针域和右指针域 ,分别用于存储左孩子结点和右孩子结点的地址。

- typedef struct BTNode
- {
- ElemType data;//数据域
- struct BTNode* lchild, * rchild;//左右孩子指针
- }BTNode,*BTree;
1.要么是个空二叉树
2.要么就是由“根结点+左子树+右子树”组成的二叉树




- BTree Creat(char str[])//先序序列建立二叉链表(方法1)
- {
- BTree T;
- static int i = 0;
- ElemType c = str[i++];
- if (c == '#')//输入#表示此结点下不存在分支
- {
- T = NULL;
- }
- else
- {
- T = (BTree)malloc(sizeof(BTree));
- if (T == NULL)
- {
- exit(0);
- }
- T->data = c;
- T->lchild = Creat(str);//递归创建左子树
- T->rchild = Creat(str);//到上一个结点的右边递归创建左右子树
- }
- return T;
- }
-
- void CreateBT(BTree& T) // 先序遍历建立二叉链表 (方法2)
- {
- ElemType ch;
- cin >> ch;
- if (ch == '^')
- T = NULL;
- else
- {
- T = (BTNode*)malloc(sizeof(BTNode));
- T->data = ch;
- cout << "请输入" << ch << "的左子树:";
- CreateBT(T->lchild);
- cout << "请输入" << ch << "的右子树:";
- CreateBT(T->rchild);
- }
- }
-
- void CreatBTNode(BTree& T, char* str)//(方法3)
- {
- BTNode* st[MAXSIZE];
- BTNode* p = NULL;
- int top = -1, k, j = 0;
- ElemType ch;
- ch = str[j];
- while (ch != '\0')//str未扫描完的时候循环
- {
- switch (ch)
- {
- case '('://为左孩子结点
- top++;
- st[top] = p;
- k = 1;
- break;
- case ')':
- top--;
- break;
- case ','://为右孩子结点
- k = 2;
- break;
- default:
- p = (BTree)malloc(sizeof(BTree));
- p->data = ch;
- p->lchild = p->rchild = NULL;
- if (T == NULL)//p结点第一次创建
- {
- T = p;
- }
- else
- {
- switch (k)
- {
- case 1:
- st[top]->lchild = p;//p结点为栈顶结点的左孩子
- break;
- case 2:
- st[top]->rchild = p;//p结点为栈顶结点的右孩子
- break;
-
- }
- }
-
- }
- ch = str[++j];//继续扫描下一个字符
- }
- }
方法3解释:例如A(B(D(,G)),C(E,F))

1.取出队头元素
2.访问该元素所指结点
3.若该元素所指结点的左、右孩子结点非空,则将该元素所指结点的左孩子和右孩子指针入队
4.若队列非空,重复1-3;当队列为空的时候,二叉树的层次遍历结束。
- void PreOrder(BTree T)//先序遍历
- {
- if (T != NULL)
- {
- cout << T->data << " ";//访问根结点
- PreOrder(T->lchild);//先序遍历左子树
- PreOrder(T->rchild);//先序遍历右子树
- }
- }
-
- void InOrder(BTree T)//中序遍历
- {
- if (T != NULL)
- {
- InOrder(T->lchild);
- cout << T->data << " ";
- InOrder(T->rchild);
- }
-
- }
- void PostOrder(BTree T)//后序遍历
- {
- if (T != NULL)
- {
- PostOrder(T->lchild);
- PostOrder(T->rchild);
- cout << T->data << " ";
- }
- }
-
-
- void LevelOrder(BTree T)//层序遍历
- {
- BTNode* p;
- BTNode* qu[MAXSIZE];//定义循环队列,存放结点指针
- int front, rear;//定义头指针和尾指针
- front = rear=0;//置队列为空队列
- rear++;//根结点指针进队
- qu[rear] = T;
- while (front != rear)//队列不为空
- {
- front = (front + 1) % MAXSIZE;//队头指针加1取模
- p = qu[front];//队头结点出队
- cout << p->data << " ";
- if (p->lchild != NULL)
- {
- rear = (rear + 1) % MAXSIZE;//队尾指针加1取模
- qu[rear] = p->lchild;//p结点的左孩子进栈
- }
- if (p->rchild != NULL)
- {
- rear = (rear + 1) % MAXSIZE;
- qu[rear] = p->rchild;//p结点的右孩子进栈
- }
- }
- }


- bool FirstOrder(BTree T)//先序遍历非递归算法
- {
- BTNode* st[MAXSIZE];//st数组存放栈元素
- // BTNode* st[MAXSIZE]因为[]的优先级比*高,所以st先与[]结合,形成数组,再与*结合,
- //所以这个数组的类型BTNode*,就是指向BTNode的指针,就是“元素是指向BTNode型数据的指针的数组”。
- // 每个元素都是一个指针,一共有MAXSIZE个元素
- int top = -1;//top为栈顶指针
- BTNode* p = T;
- while (p != NULL || top != -1)//当前结点不为空或者栈不为空
- {
- while (p != NULL)//当前结点不为空
- {
- cout << p->data << " ";
- top++;
- st[top] = p;//当前结点入栈
- p = p->lchild;//左孩子作为当前结点
- }
- if (top != -1)//当栈不为空
- {
- p = st[top];//将栈顶元素赋值给p
- top--;//栈顶元素出栈
- p = p->rchild;//指向栈顶元素的右孩子
- }
- }
- return true;
- }
-
-
- bool InOrder2(BTree T)//中序遍历非递归算法
- {
- BTNode* st[MAXSIZE];//st数组存放栈元素
- int top = -1;
- BTNode* p = T;
- while (p != NULL || top != -1)
- {
- while (p != NULL)
- {
- top++;
- st[top] = p;
- p = p->lchild;
- }
- if (top != -1)
- {
- p = st[top];//获取栈顶结点
- cout << p->data << " ";
- top--;//栈顶结点出栈
- p = p->rchild;//指向栈顶结点的右孩子
- }
- }
- return true;
- }
-
- void PostOrder2(BTree T)//后序遍历非递归算法
- {
- BTNode* st[MAXSIZE];
- BTNode* p ;
- int flag = -1;
- int top = -1;
-
- do{
- while (T != NULL)
- {
- top++;
- st[top] = T;
- T = T->lchild;
- }
- p = NULL;
- flag = 1;//表示栈顶的结点的左孩子被处理过
- while (top != -1 && flag == 1)//对栈顶结点进行连续判断
- {
- T = st[top];
- if (T->rchild == p)
- {
- cout << T->data << " ";
- top--;
- p = T;
- }
- else
- {
- T = T->rchild;
- flag = 0;//表示当前结点的左孩子没有被处理过
- }
-
- }
-
- }while (top != -1);
- cout << endl;
- }
- #include
- #include
- #include
- using namespace std;
- #define MAXSIZE 100
- typedef char ElemType;
- typedef struct BTNode
- {
- ElemType data;//数据域
- struct BTNode* lchild, * rchild;//左右孩子指针
- }BTNode, * BTree;
- BTree Creat(char str[]);//先序序列建立二叉链表(方法1)
- void CreateBT(BTree& T); // 先序遍历建立二叉链表(方法2)
- void CreatBTNode(BTree& T, char* str);//利用ch扫描,采用括号表示法表示的二叉树字符串(方法3)
-
- void PreOrder(BTree T);//先序遍历
- void InOrder(BTree T);//中序遍历
- void PostOrder(BTree T);//后序遍历
- void LevelOrder(BTree T);//层序遍历
-
- //非递归算法
- bool FirstOrder(BTree T);//先序遍历非递归算法
- bool InOrder2(BTree T);//中序遍历非递归算法
- void PostOrder2(BTree T);//后序遍历非递归算法
- //#include"TreeNode.h"
-
- BTree Creat(char str[])//先序序列建立二叉链表(方法1)
- {
- BTree T;
- static int i = 0;
- ElemType c = str[i++];
- if (c == '#')//输入#表示此结点下不存在分支
- {
- T = NULL;
- }
- else
- {
- T = (BTree)malloc(sizeof(BTree));
- if (T == NULL)
- {
- exit(0);
- }
- T->data = c;
- T->lchild = Creat(str);//递归创建左子树
- T->rchild = Creat(str);//到上一个结点的右边递归创建左右子树
- }
- return T;
- }
-
- void CreateBT(BTree& T) // 先序遍历建立二叉链表 (方法2)
- {
- ElemType ch;
- cin >> ch;
- if (ch == '^')
- T = NULL;
- else
- {
- T = (BTNode*)malloc(sizeof(BTNode));
- T->data = ch;
- cout << "请输入" << ch << "的左子树:";
- CreateBT(T->lchild);
- cout << "请输入" << ch << "的右子树:";
- CreateBT(T->rchild);
- }
- }
-
- void CreatBTNode(BTree& T, char* str)//(方法3)
- {
- BTNode* st[MAXSIZE];
- BTNode* p = NULL;
- int top = -1, k, j = 0;
- ElemType ch;
- ch = str[j];
- while (ch != '\0')//str未扫描完的时候循环
- {
- switch (ch)
- {
- case '('://为左孩子结点
- top++;
- st[top] = p;
- k = 1;
- break;
- case ')':
- top--;
- break;
- case ','://为右孩子结点
- k = 2;
- break;
- default:
- p = (BTree)malloc(sizeof(BTree));
- p->data = ch;
- p->lchild = p->rchild = NULL;
- if (T == NULL)//p结点第一次创建
- {
- T = p;
- }
- else
- {
- switch (k)
- {
- case 1:
- st[top]->lchild = p;//p结点为栈顶结点的左孩子
- break;
- case 2:
- st[top]->rchild = p;//p结点为栈顶结点的右孩子
- break;
-
- }
- }
-
- }
- ch = str[++j];//继续扫描下一个字符
- }
- }
-
-
-
- void PreOrder(BTree T)//先序遍历
- {
- if (T != NULL)
- {
- cout << T->data << " ";//访问根结点
- PreOrder(T->lchild);//先序遍历左子树
- PreOrder(T->rchild);//先序遍历右子树
- }
- }
-
- void InOrder(BTree T)//中序遍历
- {
- if (T != NULL)
- {
- InOrder(T->lchild);
- cout << T->data << " ";
- InOrder(T->rchild);
- }
-
- }
- void PostOrder(BTree T)//后序遍历
- {
- if (T != NULL)
- {
- PostOrder(T->lchild);
- PostOrder(T->rchild);
- cout << T->data << " ";
- }
- }
-
-
- void LevelOrder(BTree T)//层序遍历
- {
- BTNode* p;
- BTNode* qu[MAXSIZE];//定义循环队列,存放结点指针
- int front, rear;//定义头指针和尾指针
- front = rear = 0;//置队列为空队列
- rear++;
- qu[rear] = T;//根结点指针进队
- rear++;//队尾指针指向队尾元素的后一个位置
- front = (front + 1) % MAXSIZE;//队头指针加1取模
- while (front != rear)//队列不为空
- {
- p = qu[front];//取队头元素
- front = (front + 1) % MAXSIZE;//队头元素出队,队头指针后移
- cout << p->data << " ";
- if (p->lchild != NULL)
- {
- qu[rear] = p->lchild;//p结点的左孩子进栈
- rear = (rear + 1) % MAXSIZE;//队尾指针加1取模
- }
- if (p->rchild != NULL)
- {
- qu[rear] = p->rchild;//p结点的右孩子进栈
- rear = (rear + 1) % MAXSIZE;
- }
- }
- }
-
-
-
-
-
- bool FirstOrder(BTree T)//先序遍历非递归算法
- {
- BTNode* st[MAXSIZE];//st数组存放栈元素
- // BTNode* st[MAXSIZE]因为[]的优先级比*高,所以st先与[]结合,形成数组,再与*结合,
- //所以这个数组的类型BTNode*,就是指向BTNode的指针,就是“元素是指向BTNode型数据的指针的数组”。
- // 每个元素都是一个指针,一共有MAXSIZE个元素
- int top = -1;//top为栈顶指针
- BTNode* p = T;
- while (p != NULL || top != -1)//当前结点不为空或者栈不为空
- {
- while (p != NULL)//当前结点不为空
- {
- cout << p->data << " ";
- top++;
- st[top] = p;//当前结点入栈
- p = p->lchild;//左孩子作为当前结点
- }
- if (top != -1)//当栈不为空
- {
- p = st[top];//将栈顶元素赋值给p
- top--;//栈顶元素出栈
- p = p->rchild;//指向栈顶元素的右孩子
- }
- }
- return true;
- }
-
-
- bool InOrder2(BTree T)//中序遍历非递归算法
- {
- BTNode* st[MAXSIZE];//st数组存放栈元素
- int top = -1;
- BTNode* p = T;
- while (p != NULL || top != -1)
- {
- while (p != NULL)
- {
- top++;
- st[top] = p;
- p = p->lchild;
- }
- if (top != -1)
- {
- p = st[top];//获取栈顶结点
- cout << p->data << " ";
- top--;//栈顶结点出栈
- p = p->rchild;//指向栈顶结点的右孩子
- }
- }
- return true;
- }
-
- void PostOrder2(BTree T)//后序遍历非递归算法
- {
- BTNode* st[MAXSIZE];
- BTNode* p ;
- int flag = -1;
- int top = -1;
-
- do{
- while (T != NULL)
- {
- top++;
- st[top] = T;
- T = T->lchild;
- }
- p = NULL;
- flag = 1;//表示栈顶的结点的左孩子被处理过
- while (top != -1 && flag == 1)//对栈顶结点进行连续判断
- {
- T = st[top];
- if (T->rchild == p)
- {
- cout << T->data << " ";
- top--;
- p = T;
- }
- else
- {
- T = T->rchild;
- flag = 0;//表示当前结点的左孩子没有被处理过
- }
-
- }
-
- }while (top != -1);
- cout << endl;
- }
- //#include"TreeNode.h"
- int main()
- {
- cout << "二叉树建立的第一种方法" << endl;
- BTree T;//T为指向根结点的指针
- T=(BTree)malloc(sizeof(BTree));
- char str[] = { 'a','b','d','#','#','e','#','#','c','f','#','#','g','#','#' };
- T = Creat(str);
- cout << "先序遍历结果:";
- PreOrder(T);//先序遍历
- cout << endl;
- cout << "中序遍历结果:";
- InOrder(T);//中序遍历
- cout << endl;
- cout << "后序遍历结果:";
- PostOrder(T);//后序遍历
- cout << endl ;
- cout << "层次遍历的结果:";
- LevelOrder(T);
- cout << endl<
-
- cout << "(非递归)先序遍历结果:";
- FirstOrder(T);//先序遍历非递归算法
- cout << endl;
- cout << "(非递归)中序遍历结果:";
- InOrder2(T);//中序遍历非递归算法
- cout << endl;
- cout << "(非递归)后序遍历结果:";
- PostOrder2(T);
- cout << endl;
-
- cout << "二叉树建立的第二种方法" << endl;
- BTree T2;
- cout << "请输入第一个数据:";
- CreateBT(T2);
- cout << "先序遍历结果:";
- PreOrder(T2);
- cout << endl << endl;
-
-
- cout << "二叉树建立的第三种方法" << endl;
- BTree T3 = NULL;
- char s[] = "A(B(D(,G)),C(E,F))";
- CreatBTNode(T3, s);
- cout << "先序遍历结果是:";
- PreOrder(T3);//先序遍历
- cout << endl;
- cout << "(非递归)先序遍历结果是:";
- FirstOrder(T3);
- cout << endl;
- return 0;
- }
