#include<stdio.h>/*二叉查找树:左子树中所有关键字值小于结点关键字值X,右子树中所有关键字值大于X*/#include<stdlib.h>#ifndef_Tree_HstructTreeNode;typedefstructTreeNode*Position;typedefstructTreeNode*SreachTree;typedefint ElementType;
SreachTree MakeEmpty(SreachTree T);
Position Find(ElementType X,SreachTree T);
Position FindMin(SreachTree T);
Position FindMax(SreachTree T);
SreachTree Insert(ElementType X,SreachTree T);
SreachTree Delete(ElementType X,SreachTree T);
ElementType Retrieve(Position P);#endifstructTreeNode{
ElementType Element;
SreachTree Left;
SreachTree Right;};
SreachTree MakeEmpty(SreachTree T){if(T!=NULL){MakeEmpty(T->Left);MakeEmpty(T->Right);free(T);}returnNULL;}
Position Find(ElementType X,SreachTree T){if(T==NULL)returnNULL;if(X<T->Element)returnFind(X,T->Left);elseif(X>T->Element)returnFind(X,T->Right);elsereturn T;}
Position FindMin(SreachTree T){if(T==NULL)returnNULL;elseif(T->Left==NULL)return T;elsereturnFindMin(T->Left);}
Position FindMax(SreachTree T){if(T!=NULL){while(T->Right!=NULL){
T=T->Right;}}return T;}
SreachTree Insert(ElementType X,SreachTree T){if(T==NULL){
T=(structTreeNode*)malloc(sizeof(structTreeNode));if(T==NULL)printf("Out of space!\n");else{
T->Element=X;
T->Left=T->Right=NULL;}}elseif(X<T->Element)T->Left=Insert(X,T->Left);elseif(X>T->Element)T->Right=Insert(X,T->Right);return T;}
SreachTree Delete(ElementType X,SreachTree T){
Position Tmpcell;if(T==NULL)printf("Element not found!\n");elseif(X<T->Element){
T->Left=Delete(X,T->Left);}elseif(X>T->Element){
T->Right=Delete(X,T->Right);}elseif(T->Left&&T->Right)//X结点有两个孩子{
Tmpcell=FindMin(T->Right);
T->Element=Tmpcell->Element;
T->Right=Delete(T->Element,T->Right);}else//X结点有一个或者没有子节点 {
Tmpcell=T;if(T->Left==NULL)T=T->Right;elseif(T->Right==NULL)T=T->Left;free(Tmpcell);}return T;}
ElementType Retrieve(Position P){return P->Element;}intmain(){system("pause");return0;}
AVL树
#include<stdio.h>#include<stdlib.h>#include<math.h>#ifndef_AVLTree_HstructAvlNode;typedefstructAvlNode*Position;typedefstructAvlNode*AvlTree;typedefint ElementType;
AvlTree MakeEmpty(AvlTree T);
Position Find(ElementType X,AvlTree T);
Position FindMin(AvlTree T);
Position FindMax(AvlTree T);
AvlTree Insert(ElementType X,AvlTree T);
AvlTree Delete(ElementType X,AvlTree T);
ElementType Retrieve(Position P);#endifstructAvlNode{
ElementType Element;
AvlTree Left;
AvlTree Right;int Height;};intMax(int a,int b){if(a>b)return a;elsereturn b;}
AvlTree MakeEmpty(AvlTree T){if(T!=NULL){MakeEmpty(T->Left);MakeEmpty(T->Right);free(T);
T->Height=0;}}
Position Find(ElementType X,AvlTree T){if(T==NULL)returnNULL;if(X<T->Element)returnFind(X,T->Left);elseif(X>T->Element)returnFind(X,T->Right);elsereturn T;}
Position FindMin(AvlTree T){if(T==NULL)returnNULL;elseif(T->Left==NULL)return T;elsereturnFindMin(T->Left);}
Position FindMax(AvlTree T){if(T!=NULL){while(T->Right!=NULL){
T=T->Right;}}return T;}staticintHeight(Position P){if(P==NULL)return-1;elsereturn P->Height;}static Position SingleRotateWithLeft(Position K2){
Position K1;
K1=K2->Left;
K2->Left=K1->Right;
K1->Right=K2;
K2->Height=Max(Height(K2->Left),Height(K2->Right))+1;
K1->Height=Max(Height(K1->Left),K2->Height)+1;return K1;}static Position SingleRotateWithRight(Position K1){
Position K2;
K2=K1->Right;
K1->Right=K2->Left;
K2->Left=K1;
K1->Height=Max(Height(K1->Left),Height(K1->Right))+1;
K2->Height=Max(K1->Height,Height(K2->Right))+1;return K2;}static Position DoubleRotateWithLeft(Position K3){
K3->Left=SingleRotateWithRight(K3->Left);returnSingleRotateWithLeft(K3);}static Position DoubleRotateWithRight(Position K3){
K3->Right=SingleRotateWithLeft(K3->Right);returnSingleRotateWithRight(K3);}
AvlTree Insert(ElementType X,AvlTree T){if(T ==NULL){/*
* 一般情况为递归调用的最后一层,执行插入操作
*/
T =(structAvlNode*)malloc(sizeof(structAvlNode));if(T ==NULL){//内存不足异常}else{
T -> Element = X;
T -> Left = T -> Right =NULL;
T -> Height =0;}}elseif(X < T -> Element){/*
* 往左边递归插入
*/
T -> Left =Insert(X,T -> Left);//插入完成判断当前节点下的左子树与右子树的高度差,确定不平衡点if(Height(T -> Left)-Height(T -> Right)==2){//中间节点(T的左边节点)大于插入点元素,单旋if(X < T -> Left -> Element){
T =SingleRotateWithLeft(T);}else{
T =DoubleRotateWithLeft(T);}}}elseif(X > T -> Element){/*
* 往右边递归插入
*/
T -> Right =Insert(X,T -> Right);if(Height(T -> Right)-Height(T -> Left)==2){if(X > T -> Right -> Element){
T =SingleRotateWithRight(T);}else{
T =DoubleRotateWithRight(T);}}}//返回T的高度,T的两儿子树中最大高度 + 1
T -> Height =Max(Height(T -> Left),Height(T -> Right))+1;return T;}
AvlTree Delete(ElementType X,AvlTree T){
Position temp;if(T ==NULL){// 元素未找到异常}elseif(X < T -> Element){
T -> Left =Delete(X,T -> Left);// 判断目标节点是否不平衡if(Height(T -> Right)-Height(T -> Left)==2){/* 若不平衡,则比较目标节点(T节点)的右节点的,左、右儿子树的高度 *//* 若右儿子树高度大于左儿子树高度,单旋操作 *//* 若左儿子树高度大于右儿子树高度,双旋操作 *//* 若左、右儿子树高度相等,单旋、双旋都可(默认单旋)*/if(Height(T -> Right -> Right)<Height(T -> Right -> Left)){
T =DoubleRotateWithRight(T);}else{
T =SingleRotateWithRight(T);}}}elseif(X > T -> Element){
T -> Right =Delete(X,T -> Right);// 判断目标节点是否不平衡if(Height(T -> Left)-Height(T -> Right)==2){if(Height(T -> Left -> Right)>Height(T -> Left -> Left)){
T =DoubleRotateWithLeft(T);}else{
T =SingleRotateWithLeft(T);}}}elseif((T -> Left !=NULL)&&(T -> Right !=NULL)){/* 目标节点匹配到元素X,且有两个儿子树 *///找到目标节点右子树的最小节点
temp =FindMin(T -> Right);//最小节点的元素覆盖目标节点元素
T -> Element = temp -> Element;//递归调用,删除右子树中的最小节点
T -> Right =Delete(T -> Element,T -> Right);// 判断目标节点是否不平衡if(Height(T -> Left)-Height(T -> Right)==2){if(Height(T -> Left -> Right)>Height(T -> Left -> Left)){
T =DoubleRotateWithLeft(T);}else{
T =SingleRotateWithLeft(T);}}}else{/* 目标节点匹配到元素X,且有一个儿子树,或没有儿子树 *//* 目标节点最多只有一个儿子树,因此左子树高度为-1,右子树高度必为0 *//* 所以该目标节点处,不会发生不平衡情况 */
temp = T;if(T -> Left ==NULL){
T = T -> Right;}elseif(T -> Right ==NULL){
T = T -> Left;}free(temp);}// 计算高度
T -> Height =Max(Height(T -> Left),Height(T -> Right))+1;return T;}
ElementType Retrieve(Position P){if(P!=NULL)return P->Element;elsereturn-1;}intmain(){system("pause");return0;}
伸展树(自顶而下)
#include<stdio.h>#include<stdlib.h>#include<limits.h>typedefstructSplayNode*SplayTree;typedef SplayTree Position;typedefint ElementType;structSplayNode{
ElementType data;
Position left;
Position right;};static Position NullNode;
SplayTree InitTree();
SplayTree Splaying(SplayTree T, ElementType x);
SplayTree LLRotate(SplayTree K);
SplayTree RRRotate(SplayTree K);
SplayTree FindMax(SplayTree T);
SplayTree FindMin(SplayTree T);
SplayTree Insert(ElementType x, SplayTree T);
SplayTree Delete(ElementType x, SplayTree T);voidTraversal(SplayTree T);voidTraversal(SplayTree T,int i);
SplayTree InitTree()//初始化树,将NullNode看做NULL指针,避免了检测空树{if(NullNode ==NULL){
NullNode =(SplayTree)malloc(sizeof(SplayNode));if(NULL== NullNode){printf("error,memery is full");}//该节点的左子树和右子树指向该节点本身。
NullNode->left = NullNode->right = NullNode;}return NullNode;}
SplayTree Splaying(SplayTree T, ElementType x){//带有左指针和右指针的头结点包含了左子树和右子树的根structSplayNode Header;
Header.left = Header.right = NullNode;
Position LeftTreeMax, RightTreeMin;
LeftTreeMax = RightTreeMin =&Header;
NullNode->data = x;//这里NullNode的数据域是x//当查找到NullNode时或者是找到了x时,循环结束while(x != T->data){if(x < T->data){if(x < T->left->data){
T =LLRotate(T);}if(NullNode == T->left)//左子树为空{break;}
RightTreeMin->left = T;
RightTreeMin = T;//只要第一次左子树变为非空,那么T = T->left将会使LeftTreeMax在初始化后不再改变
T = T->left;//这样的话LeftTreeMax将仍然指向Header,它将包含右子树的根}else{if(x > T->right->data){
T =RRRotate(T);}if(NullNode == T->right)//右子树为空{break;}
LeftTreeMax->right = T;
LeftTreeMax = T;//只要第一次右子树变为非空,那么T = T->right将会使RightTreeMin在初始化后不再改变
T = T->right;}}//连接
LeftTreeMax->right = T->left;
RightTreeMin->left = T->right;
T->left = Header.right;
T->right = Header.left;return T;}
SplayTree LLRotate(SplayTree K){
Position M;
M = K->left;
K->left = M->right;
M->right = K;return M;}
SplayTree RRRotate(SplayTree K){
Position M;
M = K->right;
K->right = M->left;
M->left = K;return M;}
SplayTree FindMax(SplayTree T){
T =Splaying(T, INT_MAX);//最大值处展开return T;}
SplayTree FindMin(SplayTree T){
T =Splaying(T, INT_MIN);//最小值处展开return T;}
SplayTree Insert(ElementType x, SplayTree T){
SplayTree NewNode;
NewNode =(SplayTree)malloc(sizeof(SplayNode));if(NewNode ==NULL)printf("error ,memory is full");
NewNode->data = x;if(T == NullNode)//T是空的情形{
NewNode->left = NewNode->right = NullNode;
T = NewNode;}else{
T =Splaying(T, x);//伸展if(x < T->data){
NewNode->left = T->left;
NewNode->right = T;
T->left = NullNode;
T = NewNode;}elseif(x > T->data){
NewNode->right = T->right;
NewNode->left = T;
T->right = NullNode;
T = NewNode;}elseif(x == T->data){/* 重复值不做插入 */free(NewNode);}}return T;}
SplayTree Delete(ElementType x, SplayTree T){
Position newnode;if(T != NullNode){
T =Splaying(T, x);if(x == T->data)//找得到该元素{if(T->left == NullNode)//左子树为空{
newnode = T->right;//根就是该节点的右子树}else{
newnode = T->left;//该节点的左子树成为新根
newnode =Splaying(newnode, x);//x作为展开点,那么这个伸展操作将会把最大的节点提升至根处//那么这个根节点没有右子树(右子树为空)
newnode->right = T->right;//将原来的右子树挂上}free(T);
T = newnode;//newnode作为新的根节点}}return T;}voidTraversal(SplayTree T)//中序遍历{if(NullNode != T){Traversal(T->left);printf("%d ", T->data);Traversal(T->right);}}voidTraversal(SplayTree T,int i)//前序遍历{if(NullNode != T){printf("%d ", T->data);Traversal(T->left,1);Traversal(T->right,1);}}intmain(){
SplayTree T =InitTree();
T =Insert(7, T);
T =Insert(6, T);
T =Insert(5, T);
T =Insert(4, T);
T =Insert(3, T);
T =Insert(2, T);
T =Insert(1, T);
T =Insert(0, T);printf("前序遍历输出结果:");Traversal(T,1);printf("\n");printf("中序遍历输出结果:");Traversal(T);printf("\n");
T =Delete(4, T);printf("删除4以后前序遍历输出结果:");Traversal(T,1);printf("\n");printf("中序遍历输出结果:");Traversal(T);printf("\n");printf("树中最小值是:%d\n",FindMin(T)->data);printf("树中最大值是:%d\n",FindMax(T)->data);system("pause");return0;}
伸展树(自下而上)
#include<stdio.h>#include<stdlib.h>//伸展树的实现 typedefstructsplayNode{int element;structsplayNode* left;structsplayNode* right;}*SplayTree;
SplayTree SingleTotateWithLeft(SplayTree T);
SplayTree SingleTotateWithRight(SplayTree T);
SplayTree DoubleTotateWithLeft(SplayTree T);
SplayTree DoubleTotateWithRight(SplayTree T);
SplayTree splaying(SplayTree Root, SplayTree T, SplayTree P);voidprint(SplayTree T);voidprint(SplayTree T){//中序 if(T->left !=NULL){print(T->left);}printf("%d ", T->element);if(T->right !=NULL){print(T->right);}}voidprint2(SplayTree T){//前序 根左右printf("%d ", T->element);if(T->left !=NULL){print2(T->left);}if(T->right !=NULL){print2(T->right);}}
SplayTree insert(int X, SplayTree T){if(T ==NULL){//树为空
T =(SplayTree)malloc(sizeof(structsplayNode));
T->element = X;
T->left = T->right =NULL;}else{//不空if(X > T->element){//往右子树走
T->right =insert(X, T->right);}elseif(X < T->element){//往左子树走
T->left =insert(X, T->left);}}return T;}//查找
SplayTree find(int X, SplayTree T){if(T ==NULL){printf("tree is NULL");returnNULL;}else{
SplayTree P = T;while(P){if(X > P->element){//在右子树中
P = P->right;}elseif(X < P->element){//在左子树中
P = P->left;}elseif(X == P->element){//找到了//开始调整伸展树
T =splaying(T, T, P);return T;}}returnNULL;}}
SplayTree splaying(SplayTree Root, SplayTree T, SplayTree P){if(P->element > T->element){//比T大 往右走
T->right =splaying(Root, T->right, P);}elseif(P->element < T->element){//比T小 往左走
T->left =splaying(Root, T->left, P);}//三种情况//1要查找的结点为根结点的左右孩子 zig if(Root->left !=NULL&& Root->left == P){//是根的左孩子,实行左旋
Root =SingleTotateWithLeft(Root);return Root;}elseif(Root->right !=NULL&& Root->right == P){//是根的右孩子,实行右旋
Root =SingleTotateWithRight(Root);return Root;}//第二种情况 zig-zagif(T->left !=NULL&& T->left != P && T->left->right !=NULL&& T->left->right == P){//先右旋 后左旋 即左双旋
T =DoubleTotateWithLeft(T);}elseif(T->right !=NULL&& T->right != P && T->right->left !=NULL&& T->right->left == P){//先左旋 后右旋 即右双旋
T =DoubleTotateWithRight(T);}//第三种情况 zig-zigif(T->left !=NULL&& T->left != P && T->left->left !=NULL&& T->left->left == P){//先左旋 再左旋
T =SingleTotateWithLeft(T);
T =SingleTotateWithLeft(T);}elseif(T->right !=NULL&& T->right != P && T->right->right !=NULL&& T->right->right == P){//先右旋 再右旋
T =SingleTotateWithRight(T);
T =SingleTotateWithRight(T);}return T;}//左单旋
SplayTree SingleTotateWithLeft(SplayTree T){
SplayTree M;
M = T->left;
T->left = M->right;
M->right = T;return M;}//右单旋
SplayTree SingleTotateWithRight(SplayTree T){
SplayTree M;
M = T->right;
T->right = M->left;
M->left = T;return M;}//左双旋
SplayTree DoubleTotateWithLeft(SplayTree T){//先进行右旋 再进行左旋
T->left =SingleTotateWithRight(T->left);returnSingleTotateWithLeft(T);}//右双旋
SplayTree DoubleTotateWithRight(SplayTree T){//先进行左旋,再进行右旋
T->right =SingleTotateWithLeft(T->right);returnSingleTotateWithRight(T);}intmain(){//测试
SplayTree T =NULL;
T =insert(7, T);
T =insert(6, T);
T =insert(5, T);
T =insert(4, T);
T =insert(3, T);
T =insert(2, T);
T =insert(1, T);print2(T);
T =find(1, T);printf("查找后:");print2(T);
T =find(2, T);
T =find(5, T);printf("再次查找后:");print2(T);system("pause");return0;}