C语言实现二叉排序树

程序以'#'结尾的二叉排序树.

/*
(双重指针 BSTree *T)
问:数据结构中 二叉树建立结点为什么用 双重指针?详细解释下双重指针

答:指针的指针.
因为树的结点要用指针描述.
如果只用指针,作形参传给建立结点的函数,这个指针值传给了函数栈中的内存,函数
返回后,函数栈销毁,不能获得结点.
而用指针的指针,函数内修改了这个双重指针指向的值(即结点指针),在函数外也能获得结点.

这swap()函数要用指针而不能用值做参数一样.只是这里的值本身就是个指针,所以要用指针的指针.
*/

/*BinarySortTree*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#define SIZE 30
using namespace std;

/*二叉排序树*/
typedef struct Node
{
    int data;
    struct Node *rchild,*lchild;
}*BSTree;
stack<char> s;
/*顺序表*/
struct SeqList
{
    char data[SIZE];
};
/*创建顺序表*/
SeqList Create_SeqList(SeqList L)
{
    gets(L.data);
    return L;
}
/*插入构造二叉排序树*/
void Insert_BSTree(BSTree *T,char data)
{
    BSTree s; //新节点作为子节点或者根节点
    //树为空,创建根节点
    if(*T==NULL)
    {
        s = (BSTree)malloc(sizeof(struct Node));
        s->data = data;
        s->lchild=NULL;
        s->rchild=NULL;
        *T=s;
    }
    //小插左大插右相等扔掉
    else if(data<(*T)->data)Insert_BSTree(&((*T)->lchild),data);
    else if(data>(*T)->data)Insert_BSTree(&((*T)->rchild),data);
}
/*插入创建二叉排序树*/
void Create_BSTree(BSTree *T,SeqList L)
{
    *T=NULL;
    int k=0;
    char ch = L.data[k++];
    while(ch!='#')
    {
        Insert_BSTree(T,ch);
        ch = L.data[k++];
    }
}
/*利用栈中序遍历二叉排序树*/
void StackInOrderTraverse(BSTree root)
{
    if(root!=NULL)
    {
        StackInOrderTraverse(root->lchild);//遍历左子树
        s.push(root->data);
        StackInOrderTraverse(root->rchild);//遍历柚子树
    }
    else
    {
        stack<char> s1;//辅助栈
        //输出
        while(!s.empty())
        {
            s1.push(s.top());
            s.pop();
        }
        while(!s1.empty())
        {
            printf("%c",s1.top());
            s1.pop();
        }
    }
}

/*中序遍历二叉排序树*/
void InOrderTraverse(BSTree root)
{
    if(root!=NULL)
    {
        InOrderTraverse(root->lchild);//遍历左子树
        printf("%c",root->data);
        InOrderTraverse(root->rchild);//遍历柚子树
    }
}
/*删除功能(好难)*/
void Delete_BSTree(BSTree *T,char data)
{
    BSTree p;
    BSTree p_parent;//保存p的双亲节点
    BSTree s,s_parent;
    p = *T;
    while(p)
    {
        if(p->data==data)  //找到了
            break;
        p_parent = p; //记录前驱赋初值
        if(p->data>data)  //根节点大的话找左子树
            p = p->lchild;
        else p = p->rchild;
    }
    if(p==NULL)
    {
        printf("删除失败,没有这个数据\n");
        return;
    }
    //左子树没有的话,p可能是右子树也可能是叶子
    if(p->lchild==NULL)
    {
        //根节点
        if(p_parent==NULL){
            *T = p->rchild;
        }
        //p是双亲的左子树
        else if(p_parent->lchild==p){
            p_parent->lchild = p->rchild; //将其右子树作为它双亲的左孩子
        }
        else  p_parent->rchild = p->rchild; //将其右子树作为它双亲的右孩子
        free(p);
    }
    //左子树有的话,p可能只有左子树或者右子树左子树都有
    else {
        s_parent = p;
        s = p->lchild;
        //找到p的最右下结点
        while(s->rchild){
            s_parent = s;
            s = s->rchild;
        }
        //如果p是s的双亲节点
        if(s_parent==p){
            s_parent->lchild = s->lchild; //将s的右子树作为它右儿子
        }else s_parent->rchild = s->lchild;
        p->data = s->data;
        free(s);
    }
    printf("删除成功,删除后的序列为:\n");
    InOrderTraverse(*T);
}
int main()
{
    stack<char> s;
    char data;
    SeqList List;
    BSTree root=NULL;
    List = Create_SeqList(List);
    Create_BSTree(&root,List);
    InOrderTraverse(root);
    printf("\n");
    StackInOrderTraverse(root);
    printf("\n");
    printf("输入你想删除的数据:");
    scanf("%c",&data);
    Delete_BSTree(&root,data);
    printf("\n");
    return 0;
}

  

posted @ 2015-12-07 21:00  樱花庄的龙之介大人  阅读(993)  评论(0编辑  收藏  举报