树型结构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;}
- 树型结构1 堆排序 线索二叉树 huffman
- 数据结构-中序遍历线索二叉树,堆排序
- 树和树结构(1) : 二叉堆和堆排序
- 线索二叉树1
- 线索二叉树结构的实现
- 数据结构-排序二叉树线索化
- 数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树
- 非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树
- 二叉树堆排序
- POJ3253 Fence Repair (二叉堆 | 优先队列 | huffman树 )
- Python实现二叉树存储结构的堆排序
- 树:二叉树几种形态(满二叉,完全二叉,线索二叉,二叉排序,平衡二叉,哈夫曼)
- 线索二叉树 --->树
- 线索二叉树算法
- C#线索二叉树
- 线索二叉树
- C#线索二叉树
- 线索二叉树
- malloc、calloc和new
- oracle触发器
- 程序员的十层楼
- 挑战面试编程:最大连续子序列和
- oracle NVL、NVL2,、NULLIF、COALESCE函数的用法
- 树型结构1 堆排序 线索二叉树 huffman
- JS弹窗效果的运用(代码)
- 游标
- 自增长序列
- Java代码检查和bug分析工具
- HDOJ 3790 最短路径问题
- The source code of the Account class of the famous IM app
- 程序员怎么才能提高代码编写速度?
- Hibernate二级缓存的配置