使用顺序存储结构实现二叉树的建立、插入、查找、删除、遍历等操作。
对于含n个结点的完全二叉树中编号为i(1≤i≤n)的结点:
如果i=1,则i结点是这课完全二叉树的跟,没有双亲;否则,其双亲的编号为。
如果2i>n,则i结点没有左孩子;否则其左孩子的编号为2i。
如果2i+1>n,则i结点没有右孩子;否则其右孩子的编号为2i+1。
基本定义
//常用头文件
#include
#include
#include
//预定义常量和类型
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define NOTSEARCH -2
#define LEFT -1
#define RIGHT 1
#define MID 0
#define EXIST 2
typedef int Status;
typedef int ElemType;
typedef int Position;
typedef char TElemType;
typedef int KeyType;
typedef struct {
KeyType key;
}RcdType;
使用顺序存储结构储存二叉树,关键在于二叉树如何拓展。一般的数组,只能拥有固定长度的二叉树。因此,我们采用栈的思想,在数组满的情况下,重新申请更多的空间。
//类型定义
typedef struct {
TElemType *elem;
int lastIndex;
int size;
int increment;
}SqBiTree;
//Defination of Functions
Status InitSqBiTree(SqBiTree &T);
int SearchSqBiTree(SqBiTree T, TElemType e);
Status IncSBTree(SqBiTree &T);
Status InsertSBTNode(SqBiTree &T, TElemType insert, TElemType parents, Position insertP);
Status DeleteSBTNode(SqBiTree &T, TElemType e);
void DeleteNode(SqBiTree &T, int index);
Status DestroySqBiTree(SqBiTree &T);
Status SqBiTreeEmpty(SqBiTree T);
void Swap(int A, int B);
void PreOrderTraverse(SqBiTree T, int index, Status (*visit)(TElemType e));
void InOrderTraverse(SqBiTree T, int index, Status (*visit)(TElemType e));
void PostOrderTraverse(SqBiTree T, int index, Status (*visit)(TElemType e));
Status PrintElem(TElemType e);
void ShowSqBiTree(SqBiTree T, int index, int type, int level);
void ShowTree(SqBiTree T);
void PrintSpace(int number);
void LevelOrderTraverse(SqBiTree T, Status(*visit)(TElemType e));
Status InitSqBiTree(SqBiTree &T){
T.size = 4;//有效长度,总长度为size+1
T.increment = 3;//每次增加的长度为3
T.lastIndex = 0;//0 refers to none
T.elem = (TElemType*) malloc((T.size+1)*sizeof (TElemType));
if(NULL == T.elem)return OVERFLOW;
for(int i=1;i<=T.size;i++)T.elem[i] = '?';
T.elem[0] = '0';
return OK;
}
//寻找元素e在数组当中的位置
int SearchSqBiTree(SqBiTree T, TElemType e){
//当数组为空或者不存在的时候,返回-1
if(NULL == T.elem || TRUE == SqBiTreeEmpty(T))return -1;
//开始遍历数组
for(int i=1;i <= T.lastIndex;i++){
//如果找到,则返回当前索引
if(e == T.elem[i])return i;
}
//找不到则返回0
return 0;
}
//增长函数,用来重分配数组空间
Status IncSBTree(SqBiTree &T){
T.elem = (TElemType *)realloc(T.elem,(T.size + T.increment + 1)* sizeof(TElemType));
if(NULL == T.elem)return OVERFLOW;
//新增空间置空,这里设定字符‘0’表示空
for(int i=T.size;i<=T.size + T.increment;i++)T.elem[i] ='0';
//有效空间增加
T.size += T.increment;
return OK;
}
//插入操作,需要外部输入的参数,顺序二叉树T,插入元素insert,父母元素parents,位置参数insertP
Status InsertSBTNode(SqBiTree &T, TElemType insert, TElemType parents, Position insertP){
//如果数组不存在
if(NULL == T.elem)return ERROR;
//寻找父母元素
int parentsPosition = SearchSqBiTree(T, parents), insertIndex;
//父母元素找不到的情况
if(parentsPosition <= 0 && 0 != T.lastIndex)return NOTSEARCH;
//数组为空的情况
if(0 == T.lastIndex)insertIndex = 1;
//插入左边
else if(LEFT == insertP) insertIndex = 2 * parentsPosition;
//插入右边
else insertIndex = 2 * parentsPosition + 1;
//当空间不够的时候,不断增加空间
while(insertIndex >= T.size)IncSBTree(T);
//插入(赋值操作)
T.elem[insertIndex] = insert;
//更新最后元素索引
T.lastIndex = insertIndex > T.lastIndex ? insertIndex : T.lastIndex;
return OK;
}
//检查顺序二叉树是否为空
Status SqBiTreeEmpty(SqBiTree T){
if(NULL == T.elem)return FALSE;
return T.lastIndex == 0 ? TRUE : FALSE;
}
//SearchSqBiTree函数请查看上文
//删除结点操作
Status DeleteSBTNode(SqBiTree &T, TElemType e){
if(NULL == T.elem || TRUE == SqBiTreeEmpty(T))return ERROR;
int position = SearchSqBiTree(T,e);
if(position <= 0)return NOTSEARCH;
DeleteNode(T,position);
return OK;
}
//删除
void DeleteNode(SqBiTree &T, int index){
int left = 2*index, right = 2*index+1, max = T.lastIndex;
if(left > max && right > max || T.elem[left] == '?' && T.elem[right] == '?'){//是叶子结点
T.elem[index] = '?';
}
else if(T.elem[left] == '?' && right <= max){//无左子树
T.elem[index] = T.elem[right];
T.elem[right] = '?';
}
else if(left <= max && right > max){//无右子树1
T.elem[index] = T.elem[left];
T.elem[left] = '?';
}
else if(T.elem[right] == '?' && right <= max){//无右子树2
T.elem[index] = T.elem[left];
T.elem[right] = '?';
}
else {//既有左子树也有右子树
int parent = index, now = left;
while(2*now+1 <= max){
parent = now;
now = 2*now+1;
}
T.elem[index] = T.elem[now];
if(2*now <= max){
T.elem[now] = T.elem[2*now];
T.elem[2*now] = '?';
}
else T.elem[now] = '?';
}
//'?'的位置即相当于删除了,则更新lastIndex计数器(指针)
while(T.elem[T.lastIndex] == '?')T.lastIndex--;
}
//前序遍历
void PreOrderTraverse(SqBiTree T, int index, Status (*visit)(TElemType e)){
if(index > T.lastIndex)return;
visit(T.elem[index]);
PreOrderTraverse(T, 2*index, visit);
PreOrderTraverse(T, 2*index+1, visit);
}
//中序遍历
void InOrderTraverse(SqBiTree T, int index, Status (*visit)(TElemType e)){
if(index > T.lastIndex)return;
InOrderTraverse(T, 2*index, visit);
visit(T.elem[index]);
InOrderTraverse(T, 2*index+1, visit);
}
//后续遍历
void PostOrderTraverse(SqBiTree T, int index, Status (*visit)(TElemType e)){
if(index > T.lastIndex)return;
PostOrderTraverse(T, 2*index, visit);
PostOrderTraverse(T, 2*index+1, visit);
visit(T.elem[index]);
}
//层序遍历
//由于顺序存储结构的特性,数组中元素的顺序即为层序遍历的顺序
void LevelOrderTraverse(SqBiTree T, Status(*visit)(TElemType e)){
if(TRUE == SqBiTreeEmpty(T))return;
for(int i=1;i<=T.lastIndex;i++){
if('?' != T.elem[i])PrintElem(T.elem[i]);
}
}
Status PrintElem(TElemType e){
printf_s("%c ",e);
return OK;
}
void PrintSpace(int number){
for(int i=0;i T.lastIndex)return;
ShowSqBiTree(T, 2*index+1, RIGHT,level+1);
if(T.elem[index]!='?')
switch (type) {
case LEFT:
PrintSpace(level);
printf("\\%c\n",T.elem[index]);
break;
case RIGHT:
PrintSpace(level);
printf("/%c\n",T.elem[index]);
break;
default:
printf("%c\n",T.elem[index]);
}
ShowSqBiTree(T, 2*index, LEFT,level+1);
}
void ShowTree(SqBiTree T){
if(NULL == T.elem || 0 == T.lastIndex)printf_s("此树为空\n");
else ShowSqBiTree(T,1,MID,1);
}
谢谢各位大佬的查看,本人知识水平不高,文章有问题或者对文章内容有疑问,请在评论区和谐讨论。