二叉排序树-2

#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;
        }
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值