#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<time.h>
#include<windows.h>
#define LISTSIZE 10//初始化申请内存大小
#define ADDSIZE 1//每次增加的内存大小
#define STACKSIZE 100
typedef struct {
int *data;
int length;//所存元素占内存大小
int size;
}List,*LIST;
typedef struct node{
int key;
struct node *left;
struct node *right;
}BiTNode,*BiTree;
typedef struct {
BiTree *base;
BiTree *top;
int stacksize;
}Stack;
void InitList(List &L,int &num);
BiTree CreatTree(List L,int num);
BiTree InsertTree(BiTree root,int key);
void PRINT(List L);
void DeleteTree(BiTree &T,int key);
void InitRand(List &L,int &num);
void InOrder(BiTree T);
void OperateTree(BiTree &T,List L);
int SearchTree(BiTree T,int key);
void gotoxy(int x,int y){
COORD C;
C.X = x;
C.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),C);
}
void SetColor(unsigned short ForeColor,unsigned short BackGroundColor){
HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hCon,(ForeColor%16)|(BackGroundColor%16*16));
}
void InitStack(Stack &S){
S.base=(BiTree*)malloc(STACKSIZE*(sizeof(BiTree)));
if(!S.base){
printf("error");
exit(0);
}
S.top=S.base;
S.stacksize=STACKSIZE;
}
void PopElem(Stack &S, BiTree &T){
if(S.top==S.base){
printf("空栈");
return;
}
T=*--S.top;
}
void GetElem(Stack S, BiTree &T){
if(S.top==S.base){
printf("空栈");
return;
}
T=*(S.top-1);
}
void PushElem(Stack &S, BiTree T){
if((S.top-S.base)>=S.stacksize){
S.base=(BiTree *)realloc(S.base,(S.stacksize +ADDSIZE)*sizeof(BiTree));
if(!S.base){
printf("error");
return;
}
S.top = S.base + S.stacksize;
S.stacksize += ADDSIZE;
}
*S.top++=T;
}
void InitList(List &L,int &num){
int n,i;
L.data=(int *)malloc(LISTSIZE*sizeof(int));
if(!L.data){
printf("error");
exit(0);
}
L.length=0;
L.size = LISTSIZE;
gotoxy(20,15);
SetColor(9,0);
printf("输入你要初始化元素的个数:");
scanf("%d", &n);
num=n;
for(i=0;i<n;i++){
if(L.length==L.size){
L.data=(int *)realloc(L.data, (L.size+ADDSIZE)*sizeof(int));
if(!L.data){
printf("error");
return ;
}
L.size += ADDSIZE;
}
gotoxy(20,16+i);
SetColor(9,0);
printf("输入第%d个元素:",i+1);
scanf("%d", &L.data[i]);
L.length++;
}
}
/*构造二叉排序树*/
BiTree CreatTree(List L,int num){
BiTree root,flag;
int i;
flag=root=NULL;
for(i=0;i<num;i++)
flag=InsertTree(flag,L.data[i]);
return flag;
}
BiTree InsertTree(BiTree root,int key){
BiTree p, parent;
p=root;
while(p){
if(p->key==key)
return root;
parent=p;
p=(key<p->key)?p->left:p->right;
}
p=(BiTree)malloc(sizeof(BiTNode));
p->left=NULL;
p->right=NULL;
p->key=key;
if(root==NULL){
root=p;
}
else if(parent->key>key){
parent->left=p;
}
else{
parent->right=p;
}
return root;
}
void PRINT(List L){
int i;
for(i=0;i<L.length;i++){
SetColor(10,0);
printf("%3d: ", i+1);
SetColor(15,0);
printf("%-6d ",L.data[i]);
if((i+1)%6==0)
printf("\n");
}
}
void InOrder(BiTree T) {
BiTree p = T;
Stack S;
InitStack(S);
int i=0;
PushElem(S,p);
while((S.top-S.base) > 0) {
GetElem(S, p);
if(p == NULL)
PopElem(S, p);
/*左孩子全部入栈,最下面的孩子在栈的最上层*/
while(p != NULL) {
p = p->left;
if(p == NULL) break;
PushElem(S, p);
}
if((S.top-S.base) > 0) {
PopElem(S, p);
SetColor(10,0);
printf("%3d: ", i+1);
SetColor(15,0);
printf("%-6d ",p->key);
i ++;
if(i%6==0)
printf("\n");
/*不管右孩子是否为空,先入栈,
在最上面的if语句中进行判断*/
p = p->right;
PushElem(S, p);
}
}
}
void InitRand(List &L,int &num){
int n, i;
gotoxy(16,15);
SetColor(14,0);
printf("输入你要初始化元素的个数:");
scanf("%d", &n);
L.data=(int *)malloc(n*sizeof(int));
if(!L.data){
printf("error");
exit(0);
}
L.length=n;
L.size=n;
num=n;
srand((unsigned)time(NULL));
for(i=0; i<n; i++){
L.data[i]=rand();
}
}
void OperateTree(BiTree &T, List L){
int dat,flag,choice;
BiTree pt;
pt=T;
gotoxy(20,0);
SetColor(8, 15);
printf("输入你要查找的数:");
scanf("%d", &dat);
flag=SearchTree(T,dat);
if(flag==1){
gotoxy(20, 4);
SetColor(10,0);
printf("你所查找的数存在...\n");
while(1){
gotoxy(16,6);
SetColor(15,0);
SetColor(12,14);
printf("*******************************\n");
gotoxy(16,8);
SetColor(12,0);
printf("1.删除该节点。\n");
gotoxy(16,10);
SetColor(13,0);
printf("2.不删除。\n");
gotoxy(16,12);
SetColor(2,10);
printf("*******************************\n");
gotoxy(16,14);
SetColor(8,15);
printf("请选择:");
scanf("%d", &choice);
if(choice==1){
DeleteTree(T,dat);
SetColor(12,0);
printf("\t\t\t删除之前:\n\n");
PRINT(L);
printf("\n");
SetColor(10,0);
printf("\t\t\t删除之后:\n\n");
InOrder(T);
printf("\n");
break;
}
else if(choice==2){
InOrder(T);
break;
}
else{
printf("\t\t输入有误...\n");
}
}
}
if(flag==0){
gotoxy(20, 4);
SetColor(10,0);
printf("没有找到该节点...\n");
while(1){
gotoxy(16,6);
SetColor(15,0);
SetColor(12,14);
printf("*******************************\n");
gotoxy(16,8);
SetColor(12,0);
printf("1.添加该节点。\n");
gotoxy(16,10);
SetColor(13,0);
printf("2.不添加。\n");
gotoxy(16,12);
SetColor(2,10);
printf("*******************************\n");
gotoxy(16,14);
SetColor(8,15);
printf("请选择:");
scanf("%d", &choice);
if(choice==1){
InsertTree(T,dat);
SetColor(12,0);
printf("\t\t\t添加之前:\n\n");
PRINT(L);
printf("\n");
SetColor(10,0);
printf("\t\t\t添加之后:\n\n");
InOrder(T);
break;
}
else if(choice==2){
InOrder(T);
break;
}
else{
printf("\t\t输入有误...\n");
}
}
}
}
int SearchTree(BiTree T,int key){
if(T==NULL)
return 0;
if(key==T->key)
return 1;
if(key<T->key)
return SearchTree(T->left,key);
else
return SearchTree(T->right,key);
}
void DeleteTree(BiTree &T,int key){
BiTree pt,temp,parent=NULL;
pt=T;
while(pt){
if(pt->key==key)
break;
parent=pt;
pt=(key<pt->key)?pt->left:pt->right;
}
if(!pt)
return;
temp=pt;
if(!pt->right&&!pt->left){/*p的左右子树都为空*/
if(!parent) //要删根,须修改根指针
T=NULL;
else if(pt==parent->right)//为左儿子
parent->right=NULL;
else //为右儿子
parent->left=NULL;
free(pt);
}
else if(!pt->right){//p的右子树为空,则重接p的左子树
pt=pt->left;
if(!parent) //要删根,须修改根指针
T=pt;
else if(temp==parent->left)
parent->left=pt;
else
parent->right=pt;
free(temp);
}
else if(!pt->left) //的左子树为空,则重接p的左子树
{
pt=pt->right;
if(!parent) //要删根,须修改根指针
T=pt;
else if(temp==parent->left)
parent->left=pt;
else
parent->right=pt;
free(temp);
}
else if(pt->right&&pt->left)
{
parent=pt;
pt=pt->right;
while(pt->left)
{
parent=pt;
pt=pt->left;
}
temp->key=pt->key;
if(pt==parent->left)
parent->left=NULL;
else
parent->right=NULL;
free(pt);
}
}
int main(){
int num,choice;
BiTree root;
List L;
while(1){
gotoxy(16,0);
SetColor(15,0);
SetColor(12,14);
printf("******************************\n");
gotoxy(20,2);
SetColor(12,0);
printf("1.随机构造并输出二叉排序树\n");
gotoxy(20,4);
SetColor(13,0);
printf("2.自己构造并输出二叉排序树\n");
gotoxy(20,6);
SetColor(14,0);
printf("3.退出\n");
gotoxy(16,8);
SetColor(2,10);
printf("******************************\n");
gotoxy(20,12);
SetColor(8,15);
printf("请选择: ");
SetColor(12,14);
scanf("%d", &choice);
switch(choice){
case 1:
InitRand(L,num);
PRINT(L);
root=CreatTree(L,num);
SetColor(10,0);
printf("\n\t\t非递归输出二叉排序树:\n");
InOrder(root);
Sleep(5000);
system("cls");
OperateTree(root,L);
Sleep(10000);
system("cls");
break;
case 2:
InitList(L,num);
PRINT(L);
root=CreatTree(L,num);
SetColor(10,0);
printf("\n\t\t非递归输出二叉排序树:\n");
InOrder(root);
Sleep(10000);
system("cls");
OperateTree(root,L);
Sleep(10000);
system("cls");
break;
case 3:
exit(0);
break;
default :
printf("\t\t你的输入有误,请重新输入:");
Sleep(5000);
system("cls");
break;
}
}
}
二叉排序树-2
最新推荐文章于 2023-01-13 10:45:00 发布