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

/*
(双重指针 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;
}

  

C语言实现二叉排序树的更多相关文章

  1. 二叉排序树插入C语言版 递归步骤理解

    //二叉排序树 插入 (纯C语言实现) BTNode * BSTInsert2(BTNode *bt,int key){ //为什么纯C语言实现中 if(bt==NULL){ //要写成 bt-> ...

  2. c语言编程之二叉排序树

    二叉排序树,又称为二叉查找树.它是一颗空树,或者是具有下面的性质的二叉树: 1.若它的左子树不空,则左子树上所有节点的值均小于它的根结构的值: 2.若它的右子树不空,则右子树上所有节点的值均大于它的根 ...

  3. C语言——二叉排序树

    二叉排序树是一种实现动态查找的树表,又称二叉查找树. 二叉排序树的性质: 1. 若它的左子树不为空,则左子树上所有节点的键值均小于它的根节点键值 2. 若它的右子树不为空,则右子树上所有节点的键值均大 ...

  4. 二叉排序树思想及C语言实现

    转自: http://blog.chinaunix.net/uid-22663647-id-1771796.html 1.二叉排序树的定义 二叉排序树(Binary Sort Tree)又称二叉查找( ...

  5. [数据结构 - 第6章] 树之二叉排序树(C语言实现)

    一.什么是二叉排序树? 对于普通的顺序存储来说,插入.删除操作很简便,效率高:而这样的表由于无序造成查找的效率很低. 对于有序线性表来说(顺序存储的),查找可用折半.插值.斐波那契等查找算法实现,效率 ...

  6. 二叉查找树(二叉排序树)(C语言)

    #include<stdio.h> #include "fatal.h" struct TreeNode; typedef struct TreeNode *Posit ...

  7. 伸展树(一)之 图文解析 和 C语言的实现

    概要 本章介绍伸展树.它和"二叉查找树"和"AVL树"一样,都是特殊的二叉树.在了解了"二叉查找树"和"AVL树"之后, ...

  8. POJ 2418 各种二叉排序树

    题意很明确,统计各个字符串所占总串数的百分比,暴力的话肯定超时,看了书上的题解后发现这题主要是用二叉排序树来做,下面附上n种树的代码. 简单的二叉排序树,不作任何优化(C语言版的): #include ...

  9. 七大查找算法(附C语言代码实现)

    来自:Poll的笔记 - 博客园 链接:http://www.cnblogs.com/maybe2030/p/4715035.html 阅读目录 1.顺序查找 2.二分查找 3.插值查找 4.斐波那契 ...

随机推荐

  1. 剑桥offer(11~20)

    11.题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. class Solution { public: int NumberOf1(int n) { ; unsigned ...

  2. FreeRTOS - configASSERT(断言)的使用

    原文地址:http://www.cnblogs.com/god-of-death/p/6891400.html  FreeRTOS中的断言函数configASSERT()和标准C中的断言函数asser ...

  3. You can't specify target table 'table' for update in FROM clause

    delete from table1 where ID not in(select max(ID) ID from table1 group by row1) and row1 ) # 出现错误 # ...

  4. Java 必看的 Spring 知识汇总

    Spring框架是由于软件开发的复杂性而创建的.Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情.然而,Spring的用途不仅仅限于服务器端的开发.从简单性.可测试性和松耦 ...

  5. 修改Maven仓库地址

    在%USERPROFILE%\.m2\settings.xml例如:C:\Users\LongShu\.m2\settings.xml 可以自定义Maven的一些参数, 复制%M2_HOME%\con ...

  6. IntentServicce;Looper;long-running task

    7. If you want to carry on a long-running task, what do you need to do? IntentService:Service Servic ...

  7. No 'Access-Control-Allow-Origin' Ajax跨域访问解决方案

    No 'Access-Control-Allow-Origin' header is present on the requested resource. 当使用ajax访问远程服务器时,请求失败,浏 ...

  8. End to End Sequence Labeling via Bidirectional LSTM-CNNs-CRF论文小结

    本篇论文是卡内基梅隆大学语言技术研究所2016年  arXiv:1603.01354v5 [cs.LG] 29 May 2016 今天先理解一下这个是什么意思:        找到的相关理解:arXi ...

  9. https 多路复用的理解~转载

    https://segmentfault.com/q/1010000005167289 这里面的http/2连接是指tcp/ip层的连接还是http应用层(也就是我们平常在chrome F12 net ...

  10. Python标准库笔记(4) — collections模块

    这个模块提供几个非常有用的Python容器类型 1.容器 名称 功能描述 OrderedDict 保持了key插入顺序的dict namedtuple 生成可以使用名字来访问元素内容的tuple子类 ...