数据结构——浙大版中国大学mooc(week4)

课程给出代码

C语言表示二叉搜索树的插入和搜索

BinTree Insert( BinTree BST, ElementType X )
{
    if( !BST ){ /* 若原树为空,生成并返回一个结点的二叉搜索树 */
        BST = (BinTree)malloc(sizeof(struct TNode));
        BST->Data = X;
        BST->Left = BST->Right = NULL;
    }
    else { /* 开始找要插入元素的位置 */
        if( X < BST->Data )
            BST->Left = Insert( BST->Left, X );   /*递归插入左子树*/
        else  if( X > BST->Data )
            BST->Right = Insert( BST->Right, X ); /*递归插入右子树*/
        /* else X已经存在,什么都不做 */
    }
    return BST;
}
 
BinTree Delete( BinTree BST, ElementType X ) 
{ 
    Position Tmp; 
 
    if( !BST ) 
        printf("要删除的元素未找到"); 
    else {
        if( X < BST->Data ) 
            BST->Left = Delete( BST->Left, X );   /* 从左子树递归删除 */
        else if( X > BST->Data ) 
            BST->Right = Delete( BST->Right, X ); /* 从右子树递归删除 */
        else { /* BST就是要删除的结点 */
            /* 如果被删除结点有左右两个子结点 */ 
            if( BST->Left && BST->Right ) {
                /* 从右子树中找最小的元素填充删除结点 */
                Tmp = FindMin( BST->Right );
                BST->Data = Tmp->Data;
                /* 从右子树中删除最小元素 */
                BST->Right = Delete( BST->Right, BST->Data );
            }
            else { /* 被删除结点有一个或无子结点 */
                Tmp = BST; 
                if( !BST->Left )       /* 只有右孩子或无子结点 */
                    BST = BST->Right; 
                else                   /* 只有左孩子 */
                    BST = BST->Left;
                free( Tmp );
            }
        }
    }
    return BST;
}

C语言描述AVL树的旋转和插入

typedef struct AVLNode *Position;
typedef Position AVLTree; /* AVL树类型 */
struct AVLNode{
    ElementType Data; /* 结点数据 */
    AVLTree Left;     /* 指向左子树 */
    AVLTree Right;    /* 指向右子树 */
    int Height;       /* 树高 */
};
 
int Max ( int a, int b )
{
    return a > b ? a : b;
}
 
AVLTree SingleLeftRotation ( AVLTree A )
{ /* 注意:A必须有一个左子结点B */
  /* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */     
 
    AVLTree B = A->Left;
    A->Left = B->Right;
    B->Right = A;
    A->Height = Max( GetHeight(A->Left), GetHeight(A->Right) ) + 1;
    B->Height = Max( GetHeight(B->Left), A->Height ) + 1;
  
    return B;
}
 
AVLTree DoubleLeftRightRotation ( AVLTree A )
{ /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
  /* 将A、B与C做两次单旋,返回新的根结点C */
     
    /* 将B与C做右单旋,C被返回 */
    A->Left = SingleRightRotation(A->Left);
    /* 将A与C做左单旋,C被返回 */
    return SingleLeftRotation(A);
}
 
/*************************************/
/* 对称的右单旋与右-左双旋请自己实现 */
/*************************************/
 
AVLTree Insert( AVLTree T, ElementType X )
{ /* 将X插入AVL树T中,并且返回调整后的AVL树 */
    if ( !T ) { /* 若插入空树,则新建包含一个结点的树 */
        T = (AVLTree)malloc(sizeof(struct AVLNode));
        T->Data = X;
        T->Height = 0;
        T->Left = T->Right = NULL;
    } /* if (插入空树) 结束 */
 
    else if ( X < T->Data ) {
        /* 插入T的左子树 */
        T->Left = Insert( T->Left, X);
        /* 如果需要左旋 */
        if ( GetHeight(T->Left)-GetHeight(T->Right) == 2 )
            if ( X < T->Left->Data ) 
               T = SingleLeftRotation(T);      /* 左单旋 */
            else 
               T = DoubleLeftRightRotation(T); /* 左-右双旋 */
    } /* else if (插入左子树) 结束 */
     
    else if ( X > T->Data ) {
        /* 插入T的右子树 */
        T->Right = Insert( T->Right, X );
        /* 如果需要右旋 */
        if ( GetHeight(T->Left)-GetHeight(T->Right) == -2 )
            if ( X > T->Right->Data ) 
               T = SingleRightRotation(T);     /* 右单旋 */
            else 
               T = DoubleRightLeftRotation(T); /* 右-左双旋 */
    } /* else if (插入右子树) 结束 */
 
    /* else X == T->Data,无须插入 */
 
    /* 别忘了更新树高 */
    T->Height = Max( GetHeight(T->Left), GetHeight(T->Right) ) + 1;
     
    return T;
}

04-树7 二叉搜索树的操作集 (30 分)

函数Insert将X插入二叉搜索树BST并返回结果树的根结点指针;
函数Delete将X从二叉搜索树BST中删除,并返回结果树的根结点指针;如果X不在树中,则打印一行Not Found并返回原树的根结点指针;
函数Find在二叉搜索树BST中找到X,返回该结点的指针;如果找不到则返回空指针;
函数FindMin返回二叉搜索树BST中最小元结点的指针;
函数FindMax返回二叉搜索树BST中最大元结点的指针。
函数接口定义:
BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );

BinTree Insert( BinTree BST, ElementType X ){
    if( !BST ){ /* 若原树为空,生成并返回一个结点的二叉搜索树 */
        BST = (BinTree)malloc(sizeof(struct TNode));
        BST->Data = X;
        BST->Left = BST->Right = NULL;
    }
    else { /* 开始找要插入元素的位置 */
        if( X < BST->Data )
            BST->Left = Insert( BST->Left, X );   /*递归插入左子树*/
        else  if( X > BST->Data )
            BST->Right = Insert( BST->Right, X ); /*递归插入右子树*/
    }
    return BST;
}

BinTree Delete( BinTree BST, ElementType X ){
    Position Tmp; 
    if( !BST ) 
        printf("Not Found\n"); 
    else {
        if( X < BST->Data ) 
            BST->Left = Delete( BST->Left, X );   /* 从左子树递归删除 */
        else if( X > BST->Data ) 
            BST->Right = Delete( BST->Right, X ); /* 从右子树递归删除 */
        else { /* BST就是要删除的结点 */
            /* 如果被删除结点有左右两个子结点 */ 
            if( BST->Left && BST->Right ) {
                /* 从右子树中找最小的元素填充删除结点 */
                Tmp = FindMin( BST->Right );
                BST->Data = Tmp->Data;
                /* 从右子树中删除最小元素 */
                BST->Right = Delete( BST->Right, BST->Data );
            }
            else { /* 被删除结点有一个或无子结点 */
                Tmp = BST; 
                if( !BST->Left )       /* 只有右孩子或无子结点 */
                    BST = BST->Right; 
                else                   /* 只有左孩子 */
                    BST = BST->Left;
                free( Tmp );
            }
        }
    }
    return BST;
}

Position Find( BinTree BST, ElementType X ){
    if( !BST ) 
        return NULL; 
    else {
        if( X < BST->Data ) 
            return Find( BST->Left, X );  
        else if( X > BST->Data ) 
            return Find( BST->Right, X ); 
        else 
            return BST;
    }
}

Position FindMin( BinTree BST ){
    if(!BST)
        return NULL;
    else if(!BST->Left)
        return BST;
    else
        FindMin(BST->Left );
}

Position FindMax( BinTree BST ){
    if(!BST)
        return NULL;
    else if(!BST->Right)
        return BST;
    else
        FindMax( BST->Right );
}

04-树4 是否同一棵二叉搜索树 (25 分)

给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。
输入格式:
输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后L行,每行给出N个插入的元素,属于L个需要检查的序列。
简单起见,我们保证每个插入序列都是1到N的一个排列。当读到N为0时,标志输入结束,这组数据不要处理
输出格式:
对每一组需要检查的序列,如果其生成的二叉搜索树跟对应的初始序列生成的一样,输出“Yes”,否则输出“No”。

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode {
	ElementType Data;
	BinTree Left;
	BinTree Right;
	ElementType flag;
};

BinTree Insert(BinTree BST, ElementType X) {
	if (!BST) { /* 若原树为空,生成并返回一个结点的二叉搜索树 */
		BST = (BinTree)malloc(sizeof(struct TNode));
		BST->Data = X;
		BST->flag = 0;
		BST->Left = BST->Right = NULL;
	}
	else { /* 开始找要插入元素的位置 */
		if (X < BST->Data)
			BST->Left = Insert(BST->Left, X);   /*递归插入左子树*/
		else  if (X > BST->Data)
			BST->Right = Insert(BST->Right, X); /*递归插入右子树*/
	}
	return BST;
}

int check(BinTree BST, ElementType X) {
	if (BST->flag) {
		if (X > BST->Data)
			return check(BST->Right, X);
		else if (X < BST->Data)
			return check(BST->Left, X);
		else
			return 0;
	}
	else {
		if (X == BST->Data) {
			BST->flag = 1;
			return 1;
		}
		else
			return 0;
	}
}
int Judge(BinTree BST, ElementType X) {
	int i, V, flag1 = 0;
	scanf("%d", &V);
	if (V != BST->Data)
		flag1 = 1;
	else
		BST->flag = 1;
	for (i = 1; i < X; i++) {//一定注意从1开始!!!
		scanf("%d", &V);
		if ((!flag1) && (!check(BST, V)))
			flag1 = 1;
	}
	if (flag1)
		return 0;
	else
		return 1;
}

void ResetTree(BinTree BST) {
	if (BST->Left)
		ResetTree(BST->Left);
	if (BST->Right)
		ResetTree(BST->Right);
	BST->flag = 0;
}

int main()
{
	BinTree BST;
	ElementType X;
	int N, i, M;
	BST = NULL;
	scanf("%d", &N);
	while (N) {
		scanf("%d", &M);
		for (i = 0; i < N; i++) {
			scanf("%d", &X);
			BST = Insert(BST, X);
		}
		for (i = 0; i < M; i++) {
			if (Judge(BST, N))
				printf("Yes\n");
			else
				printf("No\n");
			ResetTree(BST);
		}
		BST=NULL;
		scanf("%d", &N);
	}
	return 0;
}

04-树5 Root of AVL Tree (25 分)

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property.
Now given a sequence of insertions, you are supposed to tell the root of the resulting AVL tree.

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct AVLNode* Position;
typedef Position AVLTree; /* AVL树类型 */
struct AVLNode {
	ElementType Data; /* 结点数据 */
	AVLTree Left;     /* 指向左子树 */
	AVLTree Right;    /* 指向右子树 */
	int Height;       /* 树高 */
};

int Max(int a, int b) {
	return a > b ? a : b;
}

int GetHeight(AVLTree A) {
	if (!A) return 0;
	if (!A->Left && !A->Right) return 1;
	if (A->Left && !A->Right) return GetHeight(A->Left) + 1;
	if (!A->Left && A->Right) return GetHeight(A->Right) + 1;
	return Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
}

AVLTree SingleLeftRotation(AVLTree A) {
	/* 注意:A必须有一个左子结点B */
	/* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */
	AVLTree B = A->Left;
	A->Left = B->Right;
	B->Right = A;
	A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
	B->Height = Max(GetHeight(B->Left), A->Height) + 1;
	return B;
}

AVLTree SingleRightRotation(AVLTree A) {
	AVLTree B = A->Right;
	A->Right = B->Left;
	B->Left = A;
	A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
	B->Height = Max(GetHeight(B->Right), A->Height) + 1;
	return B;
}

AVLTree DoubleLeftRightRotation(AVLTree A) {
	/* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
	/* 将A、B与C做两次单旋,返回新的根结点C */

	/* 将B与C做右单旋,C被返回 */
	A->Left = SingleRightRotation(A->Left);
	/* 将A与C做左单旋,C被返回 */
	return SingleLeftRotation(A);
}

AVLTree DoubleRightLeftRotation(AVLTree A) {
	A->Right = SingleLeftRotation(A->Right);
	return SingleRightRotation(A);
}

AVLTree Insert(AVLTree T, ElementType X) {
	/* 将X插入AVL树T中,并且返回调整后的AVL树 */
	if (!T) { /* 若插入空树,则新建包含一个结点的树 */
		T = (AVLTree)malloc(sizeof(struct AVLNode));
		T->Data = X;
		T->Height = 0;
		T->Left = T->Right = NULL;
	} /* if (插入空树) 结束 */
	else if (X < T->Data) {
		/* 插入T的左子树 */
		T->Left = Insert(T->Left, X);
		/* 如果需要左旋 */
		if (GetHeight(T->Left) - GetHeight(T->Right) == 2)
			if (X < T->Left->Data)
				T = SingleLeftRotation(T);      /* 左单旋 */
			else
				T = DoubleLeftRightRotation(T); /* 左-右双旋 */
	} /* else if (插入左子树) 结束 */
	else if (X > T->Data) {
		/* 插入T的右子树 */
		T->Right = Insert(T->Right, X);
		/* 如果需要右旋 */
		if (GetHeight(T->Left) - GetHeight(T->Right) == -2)
			if (X > T->Right->Data)
				T = SingleRightRotation(T);     /* 右单旋 */
			else
				T = DoubleRightLeftRotation(T); /* 右-左双旋 */
	} /* else if (插入右子树) 结束 */
	/* else X == T->Data,无须插入 */
	/* 别忘了更新树高 */
	T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1;
	return T;
}

int main(void) {
	int n, i, temp;
	AVLTree A = NULL;
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		scanf("%d", &temp);
		A = Insert(A, temp);
	}
	printf("%d\n", A->Data);
	return 0;
}

04-树6 Complete Binary Search Tree (30 分)

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties:

The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than or equal to the node’s key.
Both the left and right subtrees must also be binary search trees.
A Complete Binary Tree (CBT) is a tree that is completely filled, with the possible exception of the bottom level, which is filled from left to right.

Now given a sequence of distinct non-negative integer keys, a unique BST can be constructed if it is required that the tree must also be a CBT. You are supposed to output the level order traversal sequence of this BST.

nt root, int N, int a[])
{
    if(root<=N) {
        mid_tree(2*root, N, a);
        b[root] =  a[pos++];
        mid_tree(2*root+1, N, a);
    }
}

int main()
{
    int N, i;
    int data[1000];
    scanf("%d", &N);
    for(i=0;i<N;i++) 
        scanf("%d", &data[i]);        
    sort(data, N);
    mid_tree(1, N, data);
    for(i=1;i<=N;i++) {
        if(i==1) {
            printf("%d", b[i]);
        } else {
            printf(" %d", b[i]);
        }
    }
    return 0;
}

数组存放

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值