传统弱校HFUT的蒟蒻,真相只有一个

数据结构课程期末总结二

第一:

二叉树三种遍历方式(由前两种得到第三种 HDU1710)

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int  num=0;
struct donser
{
    int data;
    donser*lson;
    donser*rson;
};
donser *root;
donser *creat(int *a,int *b,int n)//da下标从i开始依次找  db下标从j开始向后扫  n向后扫几个
{
    donser *ss;
    for(int k=0;k<n;k++)
    {
        if(b[k]==a[0])
        {
            ss=new donser;
            ss->data=b[k];
            ss->lson=creat(a+1,b,k);
            ss->rson=creat(a+k+1,b+1+k,n-k-1);
            return ss;
        }
    }
    return NULL;
}

void solve(donser *r)
{
    if(r!=NULL)
    {
        solve(r->lson);
        solve(r->rson);
        if(r!=root) cout<<r->data<<" ";
        else cout<<r->data<<endl;
    }
}

int main()
{
    int  da[1010],db[1010];//前中
    while(~scanf("%d",&num))
    {
        for(int i=0;i<num;i++) {scanf("%d",&da[i]);}
        for(int i=0;i<num;i++) {scanf("%d",&db[i]);}
        root=creat(da,db,num);
        solve(root);
    }
    return 0;
}
View Code

 

第二:

构建一颗普通二叉树

/*
一颗普通的二叉树
*/
#include<iostream.h>
struct tree
{
    int data;
    tree *left,*right;
};
class Btree
{
    static int n;
    static int m;
public:
    tree *root;
    Btree()
    {
        root=NULL;
    }
    void create_Btree(int);
    void Preorder(tree *);                  //先序遍历
    void inorder(tree *);                   //中序遍历
    void Postorder(tree *);                 //后序遍历
    void display1()
    {
        Preorder(root);
        cout<<endl;
    }
    void display2()
    {
        inorder(root);
        cout<<endl;
    }
    void display3()
    {
        Postorder(root);
        cout<<endl;
    }
    int count(tree *);                      //计算二叉树的个数
    int findleaf(tree *);                   //求二叉树叶子的个数
    int findnode(tree *);                   //求二叉树中度数为1的结点数量,这是当初考数据结构时候的最后一道题目
};
int Btree::n=0;
int Btree::m=0;
void Btree::create_Btree(int x)
{
    tree *newnode=new tree;
    newnode->data=x;
    newnode->right=newnode->left=NULL;
    if(root==NULL)
        root=newnode;
    else
    {
        tree *back;
        tree *current=root;
        while(current!=NULL)
        {
            back=current;
            if(current->data>x)
                current=current->left;
            else
                current=current->right;
        }
        if(back->data>x)
            back->left=newnode;
        else
            back->right=newnode;
    }
}
int Btree::count(tree *p)
{
    if(p==NULL)
        return 0;
    else
        return count(p->left)+count(p->right)+1;      //这是运用了函数嵌套即递归的方法。
}
void Btree::Preorder(tree *temp)    //这是先序遍历二叉树,采用了递归的方法。
{
    if(temp!=NULL)
    {
        cout<<temp->data<<" ";
        Preorder(temp->left);
        Preorder(temp->right);
    }
}
void Btree::inorder(tree *temp)      //这是中序遍历二叉树,采用了递归的方法。
{
    if(temp!=NULL)
    {
        inorder(temp->left);
        cout<<temp->data<<" ";
        inorder(temp->right);
    }
}
void Btree::Postorder(tree *temp)     //这是后序遍历二叉树,采用了递归的方法。
{
    if(temp!=NULL)
    {
        Postorder(temp->left);
        Postorder(temp->right);
        cout<<temp->data<<" ";
    }
}
int Btree::findleaf(tree *temp)
{
    if(temp==NULL)return 0;
    else
    {
        if(temp->left==NULL&&temp->right==NULL)return n+=1;
        else
        {
            findleaf(temp->left);
            findleaf(temp->right);
        }
        return n;
    }
}
int Btree::findnode(tree *temp)
{
    if(temp==NULL)return 0;
    else
    {
        if(temp->left!=NULL&&temp->right!=NULL)
        {
            findnode(temp->left);
            findnode(temp->right);
        }
        if(temp->left!=NULL&&temp->right==NULL)
        {
            m+=1;
            findnode(temp->left);
        }
        if(temp->left==NULL&&temp->right!=NULL)
        {
            m+=1;
            findnode(temp->right);
        }
    }
    return m;
}


void main()
{
    Btree A;
    int array[]= {7,4,2,3,15,35,6,45,55,20,1,14,56,57,58};
    int k;
    k=sizeof(array)/sizeof(array[0]);
    cout<<"建立排序二叉树顺序: "<<endl;
    for(int i=0; i<k; i++)
    {
        cout<<array[i]<<" ";
        A.create_Btree(array[i]);
    }
    cout<<endl;
    cout<<"二叉树节点个数: "<<A.count(A.root)<<endl;
    cout<<"二叉树叶子个数:"<<A.findleaf(A.root)<<endl;
    cout<<"二叉树中度数为1的结点的数量为:"<<A.findnode(A.root)<<endl;
    cout<<endl<<"先序遍历序列: "<<endl;
    A.display1();
    cout<<endl<<"中序遍历序列: "<<endl;
    A.display2();
    cout<<endl<<"后序遍历序列: "<<endl;
    A.display3();
}
View Code

 

第三:

构建一棵二叉排序树并遍历输出(HDU3999)

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int ld[100010],rd[100010],a,num,root,i;
void build(int root,int al)
{
    if(al>root)
    {
        if(rd[root]==-1)
        {
            rd[root]=al;
            //cout<<"al:"<<al<<" r root:"<<root<<endl;
        }
        else build(rd[root],al);
    }
    else
    {
        if(ld[root]==-1)
        {
            ld[root]=al;
            //cout<<"al:"<<al<<" l root:"<<root<<endl;
        }
        else build(ld[root],al);
    }
}

void solve(int root)
{
    if(ld[root]!=-1)
    {
        cout<<" "<<ld[root];
        solve(ld[root]);
    }
    if(rd[root]!=-1)
    {
        cout<<" "<<rd[root];
        solve(rd[root]);
    }
    else return;
}

int main()
{
    while(~scanf("%d",&num))
    {
        memset(ld,-1,sizeof(ld));
        memset(rd,-1,sizeof(rd));
        for(i=1;i<=num;i++)
        {
            scanf("%d",&a);
            if(i==1){root=a;}
            else build(root,a);
        }
        cout<<root;
        solve(root);
        cout<<endl;
    }
    return 0;
}
View Code

 

第四:

构建一棵哈夫曼树

/*
哈夫曼树构建(最优二叉树)
*/
#include <iostream>
#include <stdlib.h>
using namespace std;
const int MaxValue = 10000;//初始设定的权值最大值
const int MaxBit = 4;//初始设定的最大编码位数
const int MaxN = 10;//初始设定的最大结点个数
struct HaffNode//哈夫曼树的结点结构
{
    int weight;//权值
    int flag;//标记
    int parent;//双亲结点下标
    int leftChild;//左孩子下标
    int rightChild;//右孩子下标
};
struct Code//存放哈夫曼编码的数据元素结构
{
    int bit[MaxBit];//数组
    int start;//编码的起始下标
    int weight;//字符的权值
};
void Haffman(int weight[], int n, HaffNode haffTree[])
//建立叶结点个数为n权值为weight的哈夫曼树haffTree
{
    int j, m1, m2, x1, x2;
    //哈夫曼树haffTree初始化。n个叶结点的哈夫曼树共有2n-1个结点
    for (int i = 0; i<2 * n - 1; i++)
    {
        if (i<n)
            haffTree[i].weight = weight[i];
        else
            haffTree[i].weight = 0;
        //注意这里没打else那{},故无论是n个叶子节点还是n-1个非叶子节点都会进行下面4步的初始化
        haffTree[i].parent = 0;
        haffTree[i].flag = 0;
        haffTree[i].leftChild = -1;
        haffTree[i].rightChild = -1;
    }
    //构造哈夫曼树haffTree的n-1个非叶结点
    for (int i = 0; i<n - 1; i++)
    {
        m1 = m2 = MaxValue;//Maxvalue=10000;(就是一个相当大的数)
        x1 = x2 = 0;//x1、x2是用来保存最小的两个值在数组对应的下标

        for (j = i; j<n + i; j++)//循环找出所有权重中,最小的二个值--morgan
        {
            if (haffTree[j].weight<m1&&haffTree[j].flag == 0)
            {
                m2 = m1;
                x2 = x1;
                m1 = haffTree[j].weight;
                x1 = j;
            }
            else if(haffTree[j].weight<m2&&haffTree[j].flag == 0)
            {
                m2 = haffTree[j].weight;
                x2 = j;
            }
        }
        //将找出的两棵权值最小的子树合并为一棵子树
        haffTree[x1].parent = n + i;
        haffTree[x2].parent = n + i;
        haffTree[x1].flag = 1;
        haffTree[x2].flag = 1;
        haffTree[n + i].weight = haffTree[x1].weight + haffTree[x2].weight;
        haffTree[n + i].leftChild = x1;
        haffTree[n + i].rightChild = x2;
    }
}
void HaffmanCode(HaffNode haffTree[], int n, Code haffCode[])
//由n个结点的哈夫曼树haffTree构造哈夫曼编码haffCode
{
    Code *cd = new Code;
    int child, parent;
    //求n个叶结点的哈夫曼编码
    for (int i = 0; i<n; i++)
    {
        //cd->start=n-1;//不等长编码的最后一位为n-1,
        cd->start = 0;//,----修改从0开始计数--morgan
        cd->weight = haffTree[i].weight;//取得编码对应权值的字符
        child = i;
        parent = haffTree[child].parent;
        //由叶结点向上直到根结点
        while (parent != 0)
        {
            if (haffTree[parent].leftChild == child)
                cd->bit[cd->start] = 0;//左孩子结点编码0
            else
                cd->bit[cd->start] = 1;//右孩子结点编码1
            //cd->start--;
            cd->start++;//改成编码自增--morgan
            child = parent;
            parent = haffTree[child].parent;
        }
        //保存叶结点的编码和不等长编码的起始位
        //for(intj=cd->start+1;j<n;j++)
        for (int j = cd->start - 1; j >= 0; j--)//重新修改编码,从根节点开始计数--morgan
            haffCode[i].bit[cd->start - j - 1] = cd->bit[j];

        haffCode[i].start = cd->start;
        haffCode[i].weight = cd->weight;//保存编码对应的权值
    }
}
int main()
{
    int i, j, n = 4, m = 0;
    int weight[] = { 2,4,5,7 };
    HaffNode*myHaffTree = new HaffNode[2 * n - 1];
    Code*myHaffCode = new Code[n];
    if (n>MaxN)
    {
        cout << "定义的n越界,修改MaxN!" << endl;
        exit(0);
    }
    Haffman(weight, n, myHaffTree);
    HaffmanCode(myHaffTree, n, myHaffCode);
    //输出每个叶结点的哈夫曼编码
    for (i = 0; i<n; i++)
    {
        cout << "Weight=" << myHaffCode[i].weight << " Code=";
        //for(j=myHaffCode[i].start+1;j<n;j++)
        for (j = 0; j<myHaffCode[i].start; j++)
            cout << myHaffCode[i].bit[j];
        m = m + myHaffCode[i].weight*myHaffCode[i].start;
        cout << endl;
    }
    cout << "huffman's WPLis:";
    cout << m;
    cout << endl;
    return 0;
}
View Code

 

posted @ 2015-12-30 16:45  未名亚柳  阅读(171)  评论(0编辑  收藏  举报