树型结构1 堆排序 线索二叉树 huffman

来源:互联网 发布:最新伪基站设备 淘宝 编辑:程序博客网 时间:2024/06/06 07:19

(1).堆排序:

使用了数组结构进行堆排序。输入一组数,输出排序后的数列。

结构如下:

struct node{

    elemtype key;

}A[maxn];

主要函数:void PushDown(int first,int last); //整理堆,维护堆的性质

  void Sort(int n); //排序总函数

思路及原理:首先把数组建立为初始堆,然后把堆顶元素与末元素交换,再用Pushdown函数维护堆(原理是向下交换,直至找到正确的位置),最后整理的堆即所求。

 

(2).哈夫曼编码与译码

使用了三态静态链表实现。输入频数,进行建立huffman树,实现编码01序列,和01序列的译码。

结构如下:

typedef struct{

    double weight;

    int lchild;

    int rchild;

    int parent;

    char data;

}HTNODE;

typedef HTNODE HuffmanT[node];

HuffmanT T;

主要函数:void SelectMin(int N,int &p1,int &p2){ //选最小的两个数,记录下标p1,p2

  void CreatHT(); //建树

  void Bianyi(); //译码函数

思路及原理:原理是使频数大的接近根。首先是huffman树的建立。每次找到最小的两个数,求和,删去这两个数,一直重复直至只剩下一个元素,即树的根。Haffman树是二叉树,令左儿子为0,右儿子为1,按照路线查找即可实现01译码。

 

(3).线索树三种遍历:

使用了线索链表存储结构实现前序中序后序遍历算法。应用功能包括建立二叉树,实现树的前序/中序/后序线索化,然后对应线索化的三种遍历输出。共九种遍历结果。

结构如下:

struct node{

    Elemtype data;

    struct node *lson,*rson;

    bool ltag,rtag; //判断是否为空

};

typedef struct node * BTREE;

主要函数:BTREE Innext(BTREE p); //二叉树查找的线索

思路及原理:线索树即使用二叉树的空指针,节约空间,提高遍历的时间。有三种线索树,包括前序、中序、后序。每种线索树又包含各自的遍历查找算法,主要就是查找线索的过程。需要理解其中的内涵。



数组存储结构实现堆排序(完全二叉树)/*    author:yjc    time:2014/3/15    title:二叉树数组存储结构堆排序*/#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int maxn=2000;typedef int elemtype;struct node{    elemtype key;}A[maxn];void Swap(node &a,node &b){    node c=a;    a.key=b.key,b.key=c.key;}void PushDown(int first,int last){    int r=first;    while(r<=last/2){        if((r==last/2) && (last%2)==0){//r有一个儿子,在2*r            if(A[r].key>A[2*r].key)                Swap(A[r],A[2*r]);            r=last;        }        else if((A[r].key>A[2*r].key) && (A[2*r].key<=A[2*r+1].key)){ //与左儿子交换            Swap(A[r],A[2*r]);            r=2*r;        }        else if((A[r].key>A[2*r].key) && (A[2*r].key>A[2*r+1].key)){ //与右儿子交换            Swap(A[r],A[2*r+1]);            r=2*r+1;        }        else r=last;    }}void Sort(int n){    for(int i=n/2;i>=1;i--)  //建立初始堆(堆逐渐扩大)        PushDown(i,n);    for(int i=n;i>=2;i--){        Swap(A[1],A[i]); //根置于末尾        PushDown(1,i-1);    }}int main(){    int n;    printf("输入数组的元素个数:");    scanf("%d",&n);    printf("输入元素:");    for(int i=1;i<=n;i++){        scanf("%d",&A[i].key);    }    Sort(n);    printf("输出排列后的元素:\n");    for(int i=1;i<=n;i++)        printf("%d ",A[i].key);    printf("\n");    return 0;}/*101 1 2 3 3 9 4 6 5 5*/三叉树Huffman的编码及译码:/*    author:yjc    time:2014/3/20    title:三叉静态链表表示Huffman树的编码与译码*/#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#define leaf 100#define node 2*(leaf)-1using namespace std;int n,m;//m=2*n-1typedef struct{    double weight;    int lchild;    int rchild;    int parent;    char data;}HTNODE;typedef HTNODE HuffmanT[node];HuffmanT T;void InitHT(){    for(int i=0;i<=leaf;i++){        T[i].parent=T[i].lchild=T[i].rchild=-1;        T[i].weight=10000;    }    printf("输入叶节点个数:");    scanf("%d",&n);    m=2*n-1;    printf("输入叶节点的权值:\n");    for(int i=0;i<n;i++){        scanf("%lf",&T[i].weight);        T[i].data='A'+i;    }}void SelectMin(int N,int &p1,int &p2){ //选最小的两个数,记录下标p1,p2    int i,j;    for(i=0;i<=N;i++)        if(T[i].parent==-1){            p1=i;            break;        }    for(j=i+1;j<=N;j++)        if(T[j].parent==-1){            p2=j;            break;        }    for(i=0;i<=N;i++)        if(T[p1].weight>T[i].weight && T[i].parent==-1 && p2!=i)            p1=i;    for(j=0;j<=N;j++)        if(T[p2].weight>T[j].weight && T[j].parent==-1 && p1!=j)            p2=j;}void CreatHT(){    int i,p1,p2;    InitHT();    for(i=n;i<m;i++){        SelectMin(i-1,p1,p2);        T[p1].parent=T[p2].parent=i;        if(T[p1].weight<=T[p2].weight){            T[i].lchild=p1;            T[i].rchild=p2;        }        else{            T[i].lchild=p2;            T[i].rchild=p1;        }        T[i].weight=T[p1].weight+T[p2].weight;    }}void Print(){    for(int i=0;i<m;i++)        printf("i=%d weight=%lf lchild=%d  rchild=%d\n",i,T[i].weight,T[i].lchild,T[i].rchild);}char str[100000];void Bianyi(){    printf("输入01字符串,中间不可以有空格:\n");    scanf("%s",str);    HTNODE p=T[m-1];    for(int i=0;i<=strlen(str);i++){        if(p.lchild==-1 && p.rchild==-1){            cout << p.data << " ";            p=T[m-1];            i--;            continue;        }        else if(str[i]=='0') p=T[p.lchild];        else if(str[i]=='1') p=T[p.rchild];    }    return;}int main(){    CreatHT();    Print();    Bianyi();    return 0;}/*50.12 0.40 0.15 0.08 0.2501011011101111*/线索二叉树的三种遍历算法:/*    author:yjc    time:2014/3/21    title:线索链表存储结构实现三种遍历算法*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <stack>#define ll long long#define CLR(x,a) memset(x,a,sizeof(x))using namespace std;const int maxn=100010;typedef char Elemtype;struct node{    Elemtype data;    struct node *lson,*rson;    bool ltag,rtag;};typedef struct node * BTREE;void menu(){    printf("Everyone loves menu!\n");    printf("1/Creat a binary tree.\n");    printf("2/Print the tree using list.\n");    printf("3/Search by preorder/inorder/postorder/levelorder.\n");    printf("4/Make full the Clue binary tree.\n");    printf("5/Search the clue binary tree.\n");    printf("0/Exit.\n");}//Second tree storing method.struct node *s[maxn];//辅助指针二叉树,存放二叉树结点指针BTREE CreatBT_other(){    int i,j;    Elemtype c;    printf("Input the node's id and data.(end with i==0 or data=='#'\n");    printf("例: A\n");    printf("    / \\ \n");    printf("   B   C\n");    printf("        \\ \n");    printf("         D\n");    printf("对应输入应该为:1 A(回车) 2 B(回车) 3 C(回车) 7 D(回车) 0 #(回车)\n");    scanf("%d %c",&i,&c);    struct node *bt,*p;    while(i!=0 && c!='#'){        p=new node;        p->data=c;        p->lson=NULL;        p->rson=NULL;        s[i]=p;        if(i==1) bt=p;        else{            j=i/2;            if(i%2==0) s[j]->lson=p;            else s[j]->rson=p;        }        scanf("%d %c",&i,&c);    }    return bt;}BTREE copy(BTREE p){    BTREE t;    if(p==NULL)t=NULL;    else    {        t=new node;        t->data=p->data;        t->lson=copy(p->lson);        t->rson=copy(p->rson);    }    return t;}//using list to express the tree.void Print(BTREE T){    if(T!=NULL){        printf("%c",T->data);        if(T->lson!=NULL||T->rson!=NULL){            printf("(");            Print(T->lson);            printf(",");            Print(T->rson);            printf(")");        }    }}//广义表2,用于线索二叉树的输出void Print2(BTREE T){    printf("%c",T->data);    if(T->ltag!=0||T->rtag!=0){        printf("(");        if(T->ltag!=0)            Print2(T->lson);        printf(",");        if(T->rtag!=0)            Print2(T->rson);        printf(")");    }}//Search using dfsvoid Preorder(BTREE BT){    if(BT!=NULL){        printf("%c",BT->data);        Preorder(BT->lson);        Preorder(BT->rson);    }}void Inorder(BTREE BT){    if(BT!=NULL){        Inorder(BT->lson);        printf("%c",BT->data);        Inorder(BT->rson);    }}void Postorder(BTREE BT){    if(BT!=NULL){        Postorder(BT->lson);        Postorder(BT->rson);        printf("%c",BT->data);    }}//Search using stack.struct node *Stack[maxn];int top;void Preorder_other(BTREE BT){    top=-1;    while(BT!=NULL || top!=-1){        while(BT!=NULL){            printf("%c",BT->data);            Stack[++top]=BT;            BT=BT->lson;        }        if(top!=-1){            BT=Stack[top--];            BT=BT->rson;        }    }}void Inorder_other(BTREE BT){    top=-1;    while(BT!=NULL || top!=-1){        while(BT!=NULL){            Stack[++top]=BT;            BT=BT->lson;        }        if(top!=-1){            BT=Stack[top--];            printf("%c",BT->data);            BT=BT->rson;        }    }}void Postorder_other2(BTREE T)//非递归后序遍历,用一个标记标记右子树是否访问过{    struct node *p;    int flag[maxn];    top=0;    p=T;    while(p!=NULL || top!=0){        while(p){            Stack[++top]=p;            flag[top]=0;            p=p->lson;        }        if(top>0){            if(flag[top]==1){                p=Stack[top--];                printf("%c",p->data);                p=NULL;            }            else{                p=Stack[top];                if(top>0){                    p=p->rson;                    flag[top]=1;                }            }        }    }}struct node *Queue[maxn],*p;void Levelorder(BTREE BT){    int pre,rear;    pre=rear=0;    if(BT==NULL) return;    Queue[++rear]=BT;    while(pre!=rear){        p=Queue[++pre];        printf("%c",p->data);        if(p->lson!=NULL) Queue[++rear]=p->lson;        if(p->rson!=NULL) Queue[++rear]=p->rson;    }}/*线索化二叉树*/BTREE pre=NULL;BTREE head;/* 二叉数的中序线索化 */void Make(BTREE p){   if(p==NULL)return ;    Make(p->lson);    p->ltag=(p->lson)?1:0;    p->rtag=(p->rson)?1:0;    if(pre)    {        if(pre->rtag==0)pre->rson=p;        if(p->ltag==0)p->lson=pre;    }    pre=p;    Make(p->rson);}BTREE Make2(BTREE p){    head=new node;    head->ltag=1;    head->rtag=0;head->rson=head;      if(!p)head->lson=head;/*若二叉树为空,则左指针回指*/      else{head->lson=p;pre=head;          Make(p);/*中序遍历进行中序线索化*/           pre->rson=head;           pre->rtag=0;/*最后一个结点线索化*/    }    return head;}/* 二叉树的先序线索化 */void ProMake(BTREE p){    if(p==NULL)return ;    p->ltag=(p->lson)?1:0;    p->rtag=(p->rson)?1:0;    if(pre)    {        if(pre->rtag==0)pre->rson=p;        if(p->ltag==0)p->lson=pre;    }    pre=p;    if(p->ltag)    ProMake(p->lson);    if(p->rtag)    ProMake(p->rson);}BTREE ProMake2(BTREE p){    head=new node;    head->rtag=0;head->rson=head;      if(!p){head->ltag=0;head->lson=head;}/*若二叉树为空,则左指针回指*/       else{            head->ltag=1;            head->lson=p;pre=head;            ProMake(p);/*先序遍历进行先序线索化*/            pre->rson=head;            pre->rtag=0;            /*最后一个结点线索化*/           }    return head;}/* 二叉树的后序线索化 */void LastMake(BTREE p){    if(p==NULL)return ;     LastMake(p->lson);     LastMake(p->rson);     p->ltag=(p->lson)?1:0;     p->rtag=(p->rson)?1:0;     if(pre)    {        if(pre->rtag==0)pre->rson=p;        if(p->ltag==0)p->lson=pre;    }      pre=p;}BTREE LastMake2(BTREE p){    head=new node;    head->rtag=0;head->rson=head;      if(!p){head->ltag=0;head->lson=head;}/*若二叉树为空,则左指针回指*/       else{ head->ltag=1;             head->lson=p;             pre=head;             LastMake(p);/*后序遍历进行后序线索化*/             head->rson=pre;                         /*最后一个结点线索化*/    }    return head;}/*线索二叉树查找的线索*///Get the inorder clue binary tree's preorder's postorder node.BTREE Innext(BTREE p){    BTREE q;    q=p->rson;    if(p->rtag==true)        while(q->ltag==true)            q=q->lson;    return q;}BTREE PreNext(BTREE p){    if(p->ltag==1)return p->lson;    return p->rson;}//后序LastNextBTREE Parent(BTREE p)  //取得节点的父节点{    BTREE temp=head;    if(temp->lson==p)        return temp;    else{        temp=temp->lson;        while(temp->lson!=p&&temp->rson!=p)        {            if(temp->rtag==1)                temp=temp->rson;            else                temp=temp->lson;  //有左孩子去左孩子,没有左孩子,去前驱;        }    }    return temp;}BTREE LastNext(BTREE p){    BTREE tmp=p,par;    if(tmp==head){        tmp=tmp->lson;        if(tmp==head)return tmp;        for(;;){            while(tmp->ltag!=0)            tmp=tmp->lson;            if(tmp->rtag!=0)            tmp=tmp->rson;            else return tmp;        }    }    else{        if(tmp->rtag==0)return tmp->rson;        else{            par=Parent(tmp);            if(par->rtag==0||par->rson==tmp)            tmp=par;            else{                while(par->rtag==1){                    par=par->rson;                    while(par->ltag==1)                        par=par->lson;                }                tmp=par;            }            return tmp;        }    }}/*线索二叉树的查找与打印*/void Thinorder(BTREE head){    BTREE temp;    temp=head;    do{        temp=Innext(temp);        if(temp==NULL) break;        if(temp!=head)            printf("%c",temp->data);    }while(temp!=head);    printf("\n");}void Thpreorder(BTREE head){     BTREE tmp;     tmp=head;     do{         tmp=PreNext(tmp);         if(tmp!=head)         printf("%c",tmp->data);     }while(tmp!=head);}void Thlastorder(BTREE head){     BTREE tmp;     tmp=head;     do{         tmp=LastNext(tmp);         if(tmp!=head)         printf("%c",tmp->data);     }while(tmp!=head);}int main(){    menu();    int choice,tmp;    BTREE T;    BTREE t1,t2,t3;    printf("Input your choice.\n");    while(scanf("%d",&choice)!=EOF){        switch(choice){            case 1:                T=CreatBT_other();                break;            case 2:                Print(T);                printf("\n");                break;            case 3:                printf("There are three searching methods,you wanted?pre/in/post/level,input 1/2/3/4.input 0 to exit this choice.\n");                while(scanf("%d",&tmp)){                    if(tmp==1) Preorder(T);                    else if(tmp==2) Inorder(T);                    else if(tmp==3) Postorder_other2(T);                    else if(tmp==4) Levelorder(T);                    else break;                    printf("\n");                }                break;            case 4:                t1=copy(T);t2=copy(t1);t3=copy(t2);              //  printf("先序线索化:");t1=PreorderTh_Make(t1);Print2(t1);printf("\n");                printf("先序线索化:");t1=ProMake2(t1);Print2(t1);printf("\n");                printf("中序线索化:");t2=Make2(t2);Print2(t2);printf("\n");                printf("后序线索化:");t3=LastMake2(t3);Print2(t3);printf("\n");                break;            case 5:                printf("对先序二叉树的非递归遍历:");Thpreorder(t1);printf("\n");                printf("对中序二叉树的非递归遍历:");Thinorder(t2);printf("\n");                printf("对后序二叉树的非递归遍历:");Thlastorder(t3);printf("\n");                break;            case 0:                return 0;        }        printf("Input your choice.\n");    }    return 0;}




0 0
原创粉丝点击