(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;
}
/*
10
1 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)-1
using namespace std;
int n,m;//m=2*n-1
typedef 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;
}
/*
5
0.12 0.40 0.15 0.08 0.25
01011011101111
*/
线索二叉树的三种遍历算法:
/*
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 dfs
void 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;
}
//后序LastNext
BTREE 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;
}