二叉搜索树,二叉堆学习

前言

Blog 好久没更新了,因为一方面忙着刷题,一方面搞大创(好浪费精力,不太想搞)

正文

今天突然不知道怎么回事,想看看之前买的数据结构书(挑战程序设计竞赛-算法和数据结构),
虽然整本书不太难,但是还是有很多不太明白的知识,光二叉搜索树就倒腾了一下午,怪我太菜了吧

BinarySearchTree

#include<bits/stdc++.h>
using namespace std;

struct node {
    int key;
    /*p是parent l是left r是right*/
    node *p,*l,*r;
};

node *root;

//插入操作
void insert(int k) {
    //y是要找的节点的父节点
    node *y = NULL;
    //x用来寻找应该插入的位置
    node *x = root;
    node *z = new node;
    z->key = k;
    z->l = NULL;
    z->r = NULL;

    while (x != NULL) {
        y = x;
        if( z->key < x->key)
            x = x->l;
        else
            x = x->r;
    }

    z->p = y;
    if(y == NULL)
        root = z;
    else {
        if(z->key < y->key)
            y->l = z;
        else
            y->r = z;
    }
}

//查找操作
node* find(node *u,int k) {
    while (u !=NULL && k != u->key) {
        if(k < u->key)
            u = u->l;
        else u = u->r;
    }
    return u;
}

//寻找最左面的节点
node* TreeMin(node *x) {
    while (x->l != NULL)
        x = x->l;
    return x;
}

//调用这个函数 就说明x下面肯定有右节点
node* TreeNext(node *x) {
    if(x->r != NULL)
        return TreeMin(x->r);
    /*
    node *y = x->p;
    while (y!=NULL && x == y->r) {
        x = y;
        y = y->p;
    }
    return y;
    */
}

//删除操作 ***慢慢理解
void Delete(node *z) {
    //y为要删除的对象 x为y子节点
    node *y,*x;

    //z没有或只有一个子节点
    if(z->l == NULL || z->r ==NULL) y=z;
    else y=TreeNext(z);  //肯定有两个子节点

    //确定y的子节点x
    if(y->l != NULL) {
        x = y->l;
    }else x = y->r;

    //删除y 就是 x 接到y的父节点上
    if(x != NULL) {
        x->p = y->p;
    }
    if(y->p == NULL) {
        root = x;
    }
    else {
        //把x接到y的父节点下
        if(y == y->p->l)
            y->p->l = x;
        else
            y->p->r = x;
    }
    if(y != z)
        z->key = y->key;
    free(y);
}


//中序遍历
void inorder(node *u) {
    if(u == NULL) return;
    inorder(u->l);
    printf(" %d",u->key);
    inorder(u->r);
}

//先序遍历
void preorder(node *u) {
    if(u == NULL) return;
    printf(" %d",u->key);
    preorder(u->l);
    preorder(u->r);
}


int main ()
{
    int n,i,x;
    string com;
    scanf("%d",&n);
    for(i=0; i<n; i++)
    {
        cin >> com;
        if(com == "insert") {
            scanf("%d",&x);
            insert(x);
        }else if(com == "find") {
            scanf("%d",&x);
            node *f = find(root,x);
            if(f != NULL)
                puts("yes");
            else
                puts("no");
        }else if(com == "delete") {
            scanf("%d",&x);
            Delete(find(root,x));
        }
        else if(com == "print") {
            inorder(root); puts("");
            preorder(root); puts("");
        }
    }
    return 0;
}

二叉堆

最大堆: 结点的键值小于等于父节点的键值
最小堆: 结点的键值大于等于父节点的键值

#include<bits/stdc++.h>
using namespace std;
#define MAX 20000

int H,A[MAX+1];

void maxHeapify(int i)
{
    int l,r,largest;
    l= 2*i, r =2*i+1;
    if(l<=H && A[l] > A[i])
        largest = l;
    else
        largest = i;
    if(r<=H && A[r] > A[largest]) largest = r;
    if(largest != i)
    {
        swap(A[i],A[largest]);
        maxHeapify(largest);
    }
}

int main ()
{
    cin >> H;
    for(int i=1;i<=H;i++)
        cin >> A[i];
    for(int i=H/2; i>=1; i--)
        maxHeapify(i);
    for(int i=1; i<=H; i++)
        cout <<" "<<A[i];

    cout << endl;
    return 0;
}

堆排序

#include<bits/stdc++.h>
using namespace std;
#define MAX 20000

int H,A[MAX+1];

void maxHeapify(int i,int len)
{
    int l,r,largest;
    l= 2*i+1, r =2*i+2;
    if(l<len && A[l] > A[i])
        largest = l;
    else
        largest = i;
    if(r<len && A[r] > A[largest]) largest = r;
    if(largest != i)
    {
        swap(A[i],A[largest]);
        maxHeapify(largest,len);
    }
}

void solve()
{
    //先把最大值放到顶端
    for(int i=H/2-1;i>=0;i--)
            maxHeapify(i,H);
    for(int i=0;i<H;i++){
        cout <<" "<<A[i];
    }cout<< endl;

    //每次把最大的放到最后
    for(int i=H-1;i>0;i--)
    {
        swap(A[0],A[i]);
        maxHeapify(0,i);
    }
    for(int i=0;i<H;i++){
        cout <<" "<<A[i];
    }
    cout << endl;

}

int main ()
{
    cin >> H;
    for(int i=0;i<H;i++)
        cin >> A[i];
    solve();
    return 0;
}

排序总结

排序总结

后记

下个月没什么特别多的事情,入门Java和Linux了,希望以后能用Java做题吧(熟悉一下Java,嘿嘿)

猜你喜欢

转载自blog.csdn.net/BING1926/article/details/79674568