1,二叉树排序算法
- 基本思想:二叉排序树:要么是空树,要么满足以下条件:若左子树不空,则左子树所有结点的值均小于根结点的值,若右子树不空,右子树所有结点的值均大于根结点的值;左子树和右子树也是一颗二叉排序树。对于二叉排序树进行中序遍历,得到就是一个有序的序列。因此二叉树排序算法是:对于待排序列,把它构建一个二叉排序树,再进行中序遍历即可,那么重点就是如何构建一个二叉排序树。其实就是进行二叉排序树的查找,先构建一颗空树,第一个元素作为此树的根结点,从第二个元素开始在此树中查找,若不存在,则,根据二叉排序树的特性在叶子结点插入,直到最后一个元素。
- 时间复杂度:nlog2(n)
- 空间复杂度:中序遍历时,需要构建栈,为logn.
这里有个很重要的点:按照二叉排序树的定义,我们是不可能在二叉排序树中看到两个或两个以上相同的元素存在,因为右>根>左;但是待排序列中的关键字总有一些是相同的,按照构建二叉排序树的方法,最后中序遍历,总有相同元素的被删掉,只保留其中一个,这样排序结果就是错的,也没法知道该算法的稳定性,那该怎么办?二叉树的插入操作是在二叉排序树中找不到的情况下插入的,这里要做些修改,就是在查找成功的条件下也要插入,怎么插入?把它插入到相同元素的的右孩子结点处,作为与其相同元素的右孩子,原来与其相同元素的右孩子插入在其右指针域,作为其右孩子。这样实际上是右>=根>左,中序遍历同样有序,并且是稳定的算法。
- 基本操作:(1),二叉排序树的查找;(2),二叉排序树的插入;(3),二叉树的中序遍历;(4),初始化栈;(5),出栈和入栈。(6),动态内存管理。
代码如下:
#include "StdAfx.h"
#include<stdio.h>
#include<malloc.h>
#define STACK_INCREMENT 10
#define STACK_INIT_SIZE 100
#define MAXSIZE 50
//二叉排序树的链式存储结构
typedef struct BiTNode
{
int data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//栈的顺序存储结构
typedef struct
{
BiTree *base;
BiTree *top;
int stacksize;
}Sqstack;
//初始化一个栈,用于二叉树的中序遍历
void InitStack(Sqstack&S)
{
S.base=(BiTree*)malloc(STACK_INIT_SIZE*sizeof(BiTNode));
if(!S.base)
exit(0);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
//二叉排序树查找
void SearchBST(BiTree T,int key,BiTree f,BiTree&p)
{
if(!T)
p=f;
else if(T->data==key)
p=T;
else if(T->data<key)
SearchBST(T->rchild,key,T,p);
else
SearchBST(T->lchild,key,T,p);
}
//创建一个二叉排序树
void CreatBST(BiTree &T,int e)
{
BiTree p,s,q;
SearchBST(T,e,NULL,p);//找到带插入的位置。
s=(BiTree)malloc(sizeof(BiTNode));
s->data=e;
s->lchild=NULL;
s->rchild=NULL;
if(!p)T=s;
else if(e==p->data)//当待排序列中有相同的元素时,将其放在相同元素的右孩子位置。原来的右子树放在其右节点域。
{
q=p->rchild;
p->rchild=s;
s->rchild=q;
}
else if(e<p->data)
p->lchild=s;
else
p->rchild=s;
}
//中序遍历二叉排序树
void InOrderTravese(BiTree T)
{
BiTree p;
Sqstack Sqt;
InitStack(Sqt);
p=T;
while(p||Sqt.base!=Sqt.top)
{
if(p)
{
if(Sqt.top-Sqt.base>=Sqt.stacksize)
{
Sqt.base=(BiTree*)realloc(Sqt.base,(Sqt.stacksize+STACK_INCREMENT)*sizeof(BiTNode));
if(!Sqt.base)
exit(OVERFLOW);
Sqt.top=Sqt.base+Sqt.stacksize;
Sqt.stacksize+=STACK_INCREMENT;
}
*Sqt.top++=p;
p=p->lchild;
}
else
{
p=*--Sqt.top;
printf("%d ",p->data);
p=p->rchild;
}
}
printf("\n");
}
void main()
{
int length;
int bst[MAXSIZE];
BiTree BST;
BST=(BiTree)malloc(sizeof(BiTNode));
BST=NULL;
printf("***************************\n");
printf(" 二叉树排序算法 \n");
printf("***************************\n");
printf("请输入待排序序列的个数N (N<%d):",MAXSIZE);
scanf("%d",&length);
printf("\n");
printf("请输入待排序的关键字:\n");
for(int i=0;i<length;i++)
scanf("%d",&bst[i]);
printf("\n");
for(int i=0;i<length;i++)
CreatBST(BST,bst[i]);
printf("输出二叉树排序结果:\n");
InOrderTravese(BST);
printf("\n");
free(BST);
}
运行结果示意图如下: