1. 程式人生 > 其它 >二叉排序樹和二叉平衡樹

二叉排序樹和二叉平衡樹

技術標籤:C++C++資料結構

(1)給定一組數
(2)程式設計實現二叉排序樹的建立、插入、刪除和查詢
(3)程式設計實現二叉平衡樹的建立、插入、刪除和查詢
(4)對於給定的這組數分別在二叉排序樹和二叉平衡樹上進行查詢,給出兩種情況下的查詢成功和不成功時的ASL

由於程式有些問題,輸入的學號和成績需要相同

程式碼結構

程式碼如下

BST.h

#ifndef BST_H_INCLUDED
#define BST_H_INCLUDED
struct student
{
    char num[6];
    int grade;
};
typedef struct BSTree
{
    struct
student data; struct BSTree *lchild; struct BSTree *rchild; } BNode,*BTree; BTree Insert(BTree T,char nums[],int grades); //²åÈë BTree Creat(BTree T,int n);//´´½¨ void midput(BTree T); void firstput(BTree T); void Search(BTree T,char num[]); //²éÕÒ
int Delete(BTree T,char * num,int key); void save(BTree T,char num[][20],int grade[]); void book(); //******************************************************* typedef struct Node { struct student data; struct Node *left; struct Node *right; int height; }BTNode; BTNode * CreatA(BTNode *T,
int n); BTNode* insertA(BTNode* node,char *num,int key); void midputA(BTNode *T); void firsputA(BTNode *T); int height(struct Node *N); int max(int a, int b); int getBalance(BTNode* N); BTNode* ll_rotate(BTNode* y); BTNode* rr_rotate(BTNode* y); BTNode* DeleteA(BTNode* root,char *num, int key); void SearchA(BTNode *T,char num[]); BTNode* newNode(char *num,int key); BTNode * minValueNode(BTNode* node); #endif // BST_H_INCLUDED

main.cpp

#include <bits/stdc++.h>
#include "BST.h"

using namespace std;

double NumOfASL_BST=0;
double NumOfASL_AVL=0;
int NumOfASL_BST_flag=0;
int NumOfASL_AVL_flag=0;

int main()
{
    BTree T=NULL;
    BTNode *TA=NULL;
    int grade,
        order;
    double  NOfSearch_AVL_Succes=0,//次數
        NOfSearch_AVL_Fail=0,
        NumOfASL_AVL_Last=0,//長度
        NumOfASL_AVL_Fail=0,

        NOfSearch_BST_Succes=0,
        NOfSearch_BST_Fail=0,
        NumOfASL_BST_Last=0,
        NumOfASL_BST_Fail=0;
    char num[6];
    while(1)
    {
        book();
        cin>>order;
        if(order==1)//建立
        {
            int NumOfStudent;
            cout<<"請輸入學生數"<<endl;
            cin>>NumOfStudent;
            cout<<"請輸入學號和成績 用空格隔開"<<endl;
            T=Creat(T,NumOfStudent);
        }
        if(order==2)//遍歷
        {
            cout<<"中序:"<<endl;
            midput(T);
            cout<<"前序:"<<endl;
            firstput(T);
        }
        if(order==3)//插入
        {
            cout<<"請輸入要插入的學生資訊"<<endl;
            cin>>num>>grade;
            T=Insert(T,num,grade);
            if(T!=NULL)
            cout<<"插入成功!"<<endl;
            else
            cout<<"插入失敗!"<<endl;;
        }
        if(order==4)//刪除
        {
            cout<<"請輸入要刪除的學生學號和成績"<<endl;
            cin>>num>>grade;
            if(Delete(T,num,grade)==1)
                cout<<"刪除成功!"<<endl;
            else
                cout<<"刪除失敗!"<<endl;
        }
        if(order==5)//查詢
        {
            NumOfASL_BST_flag=0;
            cout<<"請輸入要查詢的學生的學號"<<endl;
            cin>>num;
            NumOfASL_BST_Last=NumOfASL_BST;
            Search(T,num);
            if(NumOfASL_BST_flag==0)
            {
                NumOfASL_BST_Fail =NumOfASL_BST_Fail + (NumOfASL_BST - NumOfASL_BST_Last);
                NOfSearch_BST_Fail++;
                cout<<"查詢失敗!"<<endl;
                NumOfASL_BST=NumOfASL_BST_Last;
            }
            else
            {
                NOfSearch_BST_Succes++;
            }
            cout<<"查詢成功的總長度:"<<NumOfASL_BST<<endl;
            cout<<"查詢失敗的總長度:"<<NumOfASL_BST_Fail<<endl;
            cout<<"查詢成功的n:"<<NOfSearch_BST_Succes<<endl;
            cout<<"查詢失敗的n:"<<NOfSearch_BST_Fail<<endl;
            //dayin
            if(NOfSearch_BST_Fail==0 && NOfSearch_BST_Succes!=0)
            {
                cout<<"BST查詢失敗的ASL:"<<"暫無資料"<<endl;
                cout<<"BST查詢成功的ASL:"<<NumOfASL_BST / NOfSearch_BST_Succes<<endl;
            }
            else if(NOfSearch_BST_Succes==0 && NOfSearch_BST_Fail!=0)
            {
                cout<<"BST查詢失敗的ASL:"<<NumOfASL_BST_Fail / NOfSearch_BST_Fail<<endl;
                cout<<"BST查詢成功的ASL:"<<"暫無資料"<<endl;
            }
            else if(NOfSearch_BST_Succes==0 && NOfSearch_BST_Fail==0)
            {
                cout<<"BST查詢失敗的ASL:"<<"暫無資料"<<endl;
                cout<<"BST查詢成功的ASL:"<<"暫無資料"<<endl;
            }
            else
            {
                cout<<"BST查詢失敗的ASL:"<<NumOfASL_BST_Fail / NOfSearch_BST_Fail<<endl;
                cout<<"BST查詢成功的ASL:"<<NumOfASL_BST / NOfSearch_BST_Succes<<endl;
            }
        }
        if(order==6)
        {
            int NumOfStudent1;
            cout<<"請輸入學生數"<<endl;
            cin>>NumOfStudent1;
            cout<<"請輸入學號和相關成績 用空格隔開"<<endl;
            TA=CreatA(TA,NumOfStudent1);
        }
        if(order==7)//中序遍歷
        {
            cout<<"中序:"<<endl;
            midputA(TA);
            cout<<"前序:"<<endl;
            firsputA(TA);
        }
        if(order==8)//插入
        {
            cout<<"請輸入要插入的學生資訊"<<endl;
            cin>>num>>grade;
            TA=insertA(TA,num,grade);
            if(TA!=NULL)
            cout<<"插入成功!"<<endl;
            else
            cout<<"插入失敗。。。"<<endl;;
        }
        if(order==9)//刪除
        {
            cout<<"請輸入要刪除的學生學號和成績"<<endl;
            cin>>num>>grade;
            DeleteA(TA,num,grade);
            //if(DeleteA(TA,num,grade)==1)
                cout<<"刪除成功"<<endl;
            //else
                //cout<<"刪除失敗"<<endl;
        }
        if(order==10)//查詢
        {
            NumOfASL_AVL_flag=0;
            cout<<"請輸入要查詢的學生的學號"<<endl;
            cin>>num;
            //記錄查詢前的查詢長度
            NumOfASL_AVL_Last = NumOfASL_AVL;
            SearchA(TA,num);

            if(NumOfASL_AVL_flag==0)//查詢失敗
            {
                cout<<"查詢失敗!"<<endl;
                //計算失敗的ASL,
                NumOfASL_AVL_Fail+=NumOfASL_AVL-NumOfASL_AVL_Last;
                NumOfASL_AVL=NumOfASL_AVL_Last;
                NOfSearch_AVL_Fail++;
            }
            else//查詢成功
            {
                NOfSearch_AVL_Succes++;
            }
            cout<<"查詢成功的總長度:"<<NumOfASL_AVL<<endl;
            cout<<"查詢失敗的總長度:"<<NumOfASL_AVL_Fail<<endl;
            cout<<"查詢成功的n:"<<NOfSearch_AVL_Succes<<endl;
            cout<<"查詢失敗的n:"<<NOfSearch_AVL_Fail<<endl;
            //列印`
            if(NOfSearch_AVL_Fail==0 && NOfSearch_AVL_Succes!=0)
            {
                cout<<"AVL查詢失敗的ASL:"<<"暫無資料"<<endl;
                cout<<"AVL查詢成功的ASL:"<<NumOfASL_AVL / NOfSearch_AVL_Succes<<endl;
            }
            else if(NOfSearch_AVL_Succes==0 && NOfSearch_AVL_Fail!=0)
            {
                cout<<"AVL查詢失敗的ASL:"<<NumOfASL_AVL_Fail / NOfSearch_AVL_Fail<<endl;
                cout<<"AVL查詢成功的ASL:"<<"暫無資料"<<endl;
            }
            else if(NOfSearch_AVL_Succes==0 && NOfSearch_AVL_Fail==0)
            {
                cout<<"AVL查詢失敗的ASL:"<<"暫無資料"<<endl;
                cout<<"AVL查詢成功的ASL:"<<"暫無資料"<<endl;
            }
            else
            {
                cout<<"AVL查詢失敗的ASL:"<<NumOfASL_AVL_Fail / NOfSearch_AVL_Fail<<endl;
                cout<<"AVL查詢成功的ASL:"<<NumOfASL_AVL / NOfSearch_AVL_Succes<<endl;
            }
        }
        if(order==0)
        {
            cout<<"*                                          *"<<endl;
            cout<<"************** 感謝您的使用 ***************"<<endl;
            break;
        }
    }
    return 0;
}


AVL.cpp

#include "BST.h"
#include <bits/stdc++.h>
using namespace std;
extern double NumOfASL_AVL;
extern int NumOfASL_AVL_flag;
BTNode * CreatA(BTNode *T,int n)//建立
{
    char nums[6];
    int i,grades;
    for(i=0; i<n; i++)
    {
        cin>>nums>>grades;
        //cout<<"驗證1:"<<nums<<grades<<" ";
        T=insertA(T,nums,grades);
    }
    return T;
}  //
BTNode* insertA(BTNode* node,char *num, int key)
{

    if (node == NULL)
        return newNode(num,key);

    if (key < node->data.grade)
        node->left = insertA(node->left,num ,key);
    else if (key > node->data.grade)
        node->right = insertA(node->right,num, key);
    else
        return node;

    node->height = 1 + max(height(node->left), height(node->right));


    int balance = getBalance(node);



    if (balance > 1 && key < node->left->data.grade) //LL型
        return ll_rotate(node);


    if (balance < -1 && key > node->right->data.grade)     //RR型
        return rr_rotate(node);


    if (balance > 1 && key > node->left->data.grade)     //LR型
    {
        node->left = rr_rotate(node->left);
        return ll_rotate(node);
    }

    if (balance < -1 && key < node->right->data.grade)     //RL型
    {
        node->right = ll_rotate(node->right);
        return rr_rotate(node);
    }

    return node;
}
void midputA(BTNode *T)
{
    if(T)
    {
        midputA(T->left);
        cout<<"學號: "<<T->data.num<<" "<<"成績:"<<T->data.grade<<endl;
        midputA(T->right);
    }
}
void firsputA(BTNode *T)
{
    if(T)
    {
        cout<<"學號: "<<T->data.num<<" "<<"成績:"<<T->data.grade<<endl;
        firsputA(T->left);
        firsputA(T->right);
    }
}
int height(struct Node *N)
{
    if (N == NULL)
        return 0;
    return N->height;
}

int max(int a, int b)
{
    return (a > b) ? a : b;
}
int getBalance(BTNode* N)
{
    if (N == NULL)
        return 0;
    return height(N->left) - height(N->right);
}
BTNode* ll_rotate(BTNode* y)
{
    BTNode *x = y->left;
    y->left = x->right;
    x->right = y;

    y->height = max(height(y->left), height(y->right)) + 1;
    x->height = max(height(x->left), height(x->right)) + 1;

    return x;
}

BTNode* rr_rotate(BTNode* y)
{
    BTNode *x = y->right;
    y->right = x->left;
    x->left = y;

    y->height = max(height(y->left), height(y->right)) + 1;
    x->height = max(height(x->left), height(x->right)) + 1;

    return x;
}
BTNode* DeleteA(BTNode* root,char *num, int key)
{

    if (root == NULL)
        return root;

    if (key < root->data.grade)
        root->left = DeleteA(root->left,num, key);

    else if (key > root->data.grade)
        root->right = DeleteA(root->right,num, key);

    else
    {
        if ((root->left == NULL) || (root->right == NULL))
        {
            BTNode* temp = root->left ? root->left : root->right;

            if (temp == NULL)
            {
                temp = root;
                root = NULL;
            }
            else
                *root = *temp;
            free(temp);
        }
        else
        {
            BTNode* temp = minValueNode(root->right);

            root->data.grade = temp->data.grade;
            int b;
            for(b=0;b<6;b++)
            {
                root->data.num[b] = temp->data.num[b];
            }

            root->right = DeleteA(root->right, temp->data.num,temp->data.grade);
        }
    }


    if (root == NULL)
        return root;

    root->height = 1 + max(height(root->left), height(root->right));

    int balance = getBalance(root);


    if (balance > 1 && getBalance(root->left) >= 0) //LL型
        return ll_rotate(root);


    if (balance > 1 && getBalance(root->left) < 0) //LR型
    {
        root->left = rr_rotate(root->left);
        return ll_rotate(root);
    }

    if (balance < -1 && getBalance(root->right) <= 0) //RR型
        return rr_rotate(root);

    if (balance < -1 && getBalance(root->right) > 0)  //Rl型
    {
        root->right = ll_rotate(root->right);
        return rr_rotate(root);
    }

    return root;
}
/*void SearchA(BTNode *T,char num[]) //查詢
{
    if(T!=NULL)
    {
        NumOfASL_AVL++;
        SearchA(T->left,num);
        if(strcmp(num,T->data.num)==0)
        {
            cout<<"查詢成功"<<endl;
            cout<<"學號: "<<T->data.num<<" "<<"成績:"<<T->data.grade<<endl;
            NumOfASL_AVL_flag++;
            return;
        }
        SearchA(T->right,num);
    }
}*/
void SearchA(BTNode *T,char num[])
{
    NumOfASL_AVL++;
	if (T==NULL)  //沒找到元素
	{
		return ;
	}
	else if(strcmp(num,T->data.num)<0)
	{
        SearchA(T->left,num); //在左子樹裡面查詢
	}
	else if(strcmp(num,T->data.num)>0)
	{
		SearchA(T->right,num); //在右子樹裡面查詢
	}
	else //相等
    {
        cout<<"查詢成功!"<<endl;
        cout<<"學號: "<<T->data.num<<" "<<"成績:"<<T->data.grade<<endl;
        NumOfASL_AVL_flag++;
        return ;
    }
}
BTNode* newNode(char *num,int key)
{
    struct Node* node = (BTNode*)malloc(sizeof(struct Node));
    node->data.grade= key;
    int c;
    for(c=0;c<6;c++)
    {
        node->data.num[c]= num[c];
    }
    node->left = NULL;
    node->right = NULL;
    node->height = 1;
    return(node);
}
BTNode * minValueNode(BTNode* node)
{
    BTNode* current = node;

    while (current->left != NULL)
        current = current->left;

    return current;
}

BST.cpp

#include <bits/stdc++.h>
#include "BST.h"
using namespace std;
extern double NumOfASL_BST;
extern int NumOfASL_BST_flag;
BTree Insert(BTree T,char *nums,int grades) //插入
{
    int i;
    if(!T)//T結點為空
    {
        T=new BNode;
        T->lchild=NULL;
        T->rchild=NULL;
        for(i=0; i<6; i++)
        {
            T->data.num[i]=nums[i];
        }
        T->data.grade=grades;
        //cout<<"學號: "<<T->data.num<<" "<<"成績:"<<T->data.grade<<endl;
        return T;
    }
    else//非空
    {
        //  cout<<"*********";
        if(grades>=T->data.grade)//大的放在右
            T->rchild=Insert(T->rchild,nums,grades);
        else if(grades<T->data.grade)//小的放左
            T->lchild=Insert(T->lchild,nums,grades);
        return T;
    }
}
BTree Creat(BTree T,int n)//建立
{
    char nums[6];
    int i,grades;
    for(i=0; i<n; i++)
    {
        cin>>nums>>grades;
        //cout<<"驗證1:"<<nums<<grades<<" ";
        T=Insert(T,nums,grades);
    }
    return T;
}  //
void midput(BTree T)
{
    if(T)
    {
        midput(T->lchild);
        cout<<"學號: "<<T->data.num<<" "<<"成績:"<<T->data.grade<<endl;
        midput(T->rchild);
    }
}
void firstput(BTree T)
{
    if(T)
    {
        cout<<"學號: "<<T->data.num<<" "<<"成績:"<<T->data.grade<<endl;
        firstput(T->lchild);
        firstput(T->rchild);
    }
}
void Search(BTree T,char num[])
{
    NumOfASL_BST++;
	if (T==NULL)  //沒找到元素
	{
		return ;
	}
	else if(strcmp(num,T->data.num)<0)
	{
        Search(T->lchild,num); //在左子樹裡面查詢
	}
	else if(strcmp(num,T->data.num)>0)
	{
		Search(T->rchild,num); //在右子樹裡面查詢
	}
	else //相等
    {
        cout<<"查詢成功!"<<endl;
        cout<<"學號: "<<T->data.num<<" "<<"成績:"<<T->data.grade<<endl;
        NumOfASL_BST_flag++;
        return ;
    }
}
void save(BTree T,char num[][20],int grade[])
{
    static int x=0;
    if(T)
    {
        strcpy(num[x],T->data.num);
        grade[x]=T->data.grade;
        x++;
        save(T->lchild,num,grade);
        save(T->rchild,num,grade);
    }
}
int Delete(BTree T,char *num,int key)
{
    BTree p,f,q,s;
    p=T;//p為要刪除的節點
    f=NULL;//f為p的父節點
    while(p)//找到key的位置(即p的位置)
    {
        if(strcmp(num,p->data.num)==0)
            break;
        f=p;
        if(key<p->data.grade)
            p=p->lchild;
        else if(key>p->data.grade)
            p=p->rchild;
    }
    if(p==NULL) return 0;//判斷空樹

    if(p->lchild==NULL)
    {
        if(f==NULL)
            p=p->rchild;
        else if(f->lchild==p)
            f->lchild=p->rchild;
        else if(f->rchild==p)
            f->rchild=p->rchild;
        free(p);
    }
    else
    {
        q=p;
        s=p->lchild;
        while(s->rchild)
        {
            q=p;
            s=s->rchild;
        }
        if(q==p)
            p->lchild=s->lchild;//如果p的左孩子沒有右孩子,則直接把p的左孩子往上移
        else q->rchild=s->lchild;
        strcpy(p->data.num,s->data.num);
        p->data.grade=s->data.grade;
        free(s);
    }
    return 1;
}
void book()
{
    cout<<"**************歡迎使用本系統 ***************"<<endl;
    cout<<"* 二叉排序樹操作:                         *"<<endl;
    cout<<"*        1.建立二叉排序樹                  *"<<endl;
    cout<<"*        2.中序/前序遍歷                   *"<<endl;
    cout<<"*        3.向二叉樹插入一條學生記錄        *"<<endl;
    cout<<"*        4.從二叉樹中刪除一條學生記錄      *"<<endl;
    cout<<"*        5.從二叉樹中查詢一條學生記錄      *"<<endl;
    cout<<"*                                          *"<<endl;
    cout<<"* 二叉平衡樹操作:                         *"<<endl;
    cout<<"*        6.建立二叉平衡樹                  *"<<endl;
    cout<<"*        7.中序/前序遍歷                   *"<<endl;
    cout<<"*        8.向二叉樹插入一條學生記錄        *"<<endl;
    cout<<"*        9.從二叉樹中刪除一條學生記錄      *"<<endl;
    cout<<"*        10.從二叉樹中查詢一條學生記錄     *"<<endl;
    cout<<"*                                          *"<<endl;
    cout<<"*        0.退出系統                        *"<<endl;
}