标签:
今天应同学之邀,写了一个二叉排序树,有不足的地方请指正,还有就是实现那个栈中序遍历功能,我也没弄懂,就根据自己的理解写吧,顺便扩展一点双重指针的知识,其实用C语言最烦指针了,感觉用java就不用考虑,这个程序是以‘#‘结尾的二叉排序树.
/*
(双重指针 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; }
标签:
原文地址:http://www.cnblogs.com/liyinggang/p/5027426.html