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

/*
(双重指针 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. C/C++中字符串与数字相互转换

    数字转字符串: 用C++的streanstream: #include <sstream> #Include <string> string num2str(double i) ...

  2. angular 前台代码分层方法

    原代码: 现在将 findAll的get请求部分抽取成 服务,服务就是 $http.get 其实就是 ang内置的服务,其实就是可能会公用的方法,即可能被多个控制器调用的方法 比如这里认为 get请求 ...

  3. Efficient Deblurring for Shaken and Partially Saturated Images

    Try the online demo: http://willow-fd.rocq.inria.fr/unshake/ Overview One common feature of “shaken” ...

  4. 理解Linux文件系统挂载参数noatime nodiratime

    很多线上服务器为了提供文件系统IO性能,会在挂载文件系统的时候指定“noatime,nodiratime”参数,意味着当访问一个文件和目录的时候,access time都不会更新.但是如果未指定上面的 ...

  5. linux环境下,接着lnmp,安装redis

    linux环境下,安装redis   操作记录: 回到家目录 cd ~查看   ls进入   lump cd lnmp1.3-fullls??? sudo  ./addons.sh //---进入后选 ...

  6. 在centos中使用rpm安装包安装jenkins

    jenkins下载:http://pkg.jenkins-ci.org/redhat/ 下载rpm包到本地 在linux下使用rpm包安装命令: sudo rpm -ih jenkins-1.562- ...

  7. C++ 指针常见用法小结

    1. 概论 2.指针基础 3. 指针进阶 4. 一维数组的定义与初始化 5. 指针和数组 6. 指针运算 7. 多维数组和指针 8. 指针形参 9. 数组形参 10. 返回指针和数组 11. 结语   ...

  8. 1-shell学习(bash)

    1.为什么需要学习shell: (1)通用性,基本上所有的linux机器都会支持 (2)文字传输操作更快 (3)以后的系统管理需要使用 2.知识点: (1)变量相关:

  9. LightOJ 1340 - Story of Tomisu Ghost 阶乘分解素因子

    http://www.lightoj.com/volume_showproblem.php?problem=1340 题意:问n!在b进制下至少有t个后缀零,求最大的b. 思路:很容易想到一个数通过分 ...

  10. Bat 命令相关

    1. bat 里面怎么sleep 等待: ping 127.0.0.1 -n 2000 > nul 2. net use 建立映射: net use Y: \\172.16.10.240\Inf ...