数据结构典型算法的VC实现(袁辉勇)

1、	迷宫问题求解
#include <stdio.h>
#define m 8 //迷宫内有8列
#define n 8 //迷宫内有8行
#define MAXSIZE 100//栈尺寸最大为100
int maze[m+2][n+2]=   //迷宫情况,见书P50页图3.4,    1代表不可走,0代表可走
	{
	 {1,1,1,1,1,1,1,1,1,1},
	 {1,0,0,1,0,0,0,1,0,1},
	 {1,0,0,1,0,0,0,1,0,1},
	 {1,0,0,0,0,1,1,0,0,1},
	 {1,0,1,1,1,0,0,0,0,1},
	 {1,0,0,0,1,0,0,0,0,1},
	 {1,0,1,0,0,0,1,0,0,1},
	 {1,0,1,1,1,0,1,1,0,1},
	 {1,1,0,0,0,0,0,0,0,1},
	 {1,1,1,1,1,1,1,1,1,1}
	 };


typedef struct{
	int x;		//x坐标
	int y;		//y坐标
	int d;		//行走的方向
}DataType;		//每个点的情况,入栈的点结构

typedef struct{
	DataType point[MAXSIZE];
	int top;
	int stacksize;
}SeqStack;		//顺序栈的数据结构,用于存放行走的路线

typedef struct{
	int x;
	int y;
}item;			//按指定方向行走要对x,y所做的修改

void initStack(SeqStack *s)			//路线栈初始化
{
	s->top=-1;
}

int stackEmpty(SeqStack s)			//判断是否为空栈
{
	if(s.top==-1)return 1;
	return 0;
}

void push(SeqStack *s, DataType e)			//新点入路线栈,即前进一步
{
	int top;
	if(s->top==MAXSIZE-1){printf("Stack is full!
");return;}
	s->top++;

	top=s->top;
	s->point[top].x=e.x;
	s->point[top].y=e.y;
	s->point[top].d=e.d;
}

void pop(SeqStack *s, DataType *e)			//从路线栈中弹出一个点,即回退一步
{
	if(s->top==-1){printf("Stack is empty!
");return ;}
	e->x=s->point[s->top].x;
	e->y=s->point[s->top].y;
	e->d=s->point[s->top].d;

	s->top--;

}

void StackTravel(SeqStack s)		//将路线栈中的元素依次输出
{
	int i=1;
	DataType e;
	printf("
NO.---------> x       y        direction
");
	while(!stackEmpty(s))
	{
		pop(&s,&e);
		printf("%2d %10d%10d%10d
",i++,e.x,e.y,e.d);
	}
}



int path(int maze[m+2][n+2],item move[]) //迷宫找路算法
{
	SeqStack S;
	DataType temp;
	int x,y,d;
	int i,j;
	initStack(&S);
	temp.x=1; temp.y=1; temp.d=-1;//第一个点为1,1,起始方向为-1
	push(&S,temp);//第一个点进栈
	while(!stackEmpty(S))//如果栈中有元素则还可以进行试探,否则回退到了起点则表明此迷宫无路可行
	{
		pop(&S,&temp);//先退回一步
		x=temp.x;
		y=temp.y;
		d=temp.d+1;//将原栈顶点的坐标和行走方向记录下来
		while(d<4)//检查是否已经试探了4个方向.如果小于4个方向则更换试探方向,并根据试探方向修改新点的坐标
		{
			i=x+move[d].x;//新点的x
			j=y+move[d].y;//新点的y
			if(maze[i][j]==0)//如果新点是可通的,即maze[i][j]为0
			{
				temp.x=x;
				temp.y=y;
				temp.d=d;
				push(&S,temp);//新点记录下来并进栈
				x=i;y=j;//将新点变为当前点
				maze[x][y]=-1;//将进栈点打上"走过"标记,即设置为-1
				if(x==m&&y==n)//如果坐标与出口坐标一致则表明到达出口
				{
					StackTravel(S);
					return 1;
				}
				else d=0;
			}/* if(maze)==0)*/
			else d++;//新点不可通行则调整行进方向
		}/*end while(d<4)所有方向均试探完毕*/
	}/*end while(!stackEmpty(S))回到了入口位置*/
	return 0;
}


main()
{
	item move[4]={{0,1},{1,0},{0,-1},{-1,0},};//由方向决定如何移动,按东南西北四个方向
	int result;
	result=path(maze,move);
	if(result==1)printf("I find the path!
");//结果为1表明找到了出路
	else printf("I can't find the path!
");//否则表明找不到出路,迷宫不可通行
}




2、	表达式求值
#define stackinitsize 20
#define stackincrement 8
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
char table[7][8]={">><<<>>",">><<<>>",">>>><>>",
       ">>>><>>","<<<<<= ",">>>> > ","<<<<< ="};
char *s_operator="+-*/()#";
char *validchar="+-*/()#0123456789";

typedef struct{
  int *base;
  int *top;
  int stacksize;
}sqstack;

int  initstack(sqstack *s)
  {(*s).base=(int * ) malloc(stackinitsize*sizeof(int));
   (*s).top=(*s).base;
   (*s).stacksize=stackinitsize;
   return 1;
   }

int push(sqstack *s,int e)
 {
   *((*s).top)=e;
   (*s).top++;
   return 1;
 }

int gettop(sqstack s)
{
  return *(s.top-1);
 }

int emptystack(sqstack s)
  {if (s.top==s.base)  return 1;
   else return 0;
   }

int pop(sqstack *s,int *e)
   { if (emptystack(*s)) return 0;
     --(*s).top;
     *e=*(*s).top;
    return 1;
     }

void print(sqstack s)
 { int t;
    while(!emptystack(s))
     {pop(&s,&t);
      printf("%d ",t);
      }
     printf("
");
 }


int ctoi(char ch)
{ switch(ch)
  {case '+':return 0;
   case '-':return 1;
   case '*':return 2;
   case '/':return 3;
   case '(':return 4;
   case ')':return 5;
   case '#':return 6;
 }
}

char precede(char c1,char c2)
 { return table[ctoi(c1)][ctoi(c2)];
 }

int in(char c1,char *op)
 {  char *s;
    s=op;
    while (*s&&*s!=c1) s++;
    if (*s)  return 1;
      else return 0;
 }

int valid(char c1,char *op)
 {  char *s;
    s=op;
    while (*s&&*s!=c1) s++;
    if (*s)  return 1;
      else return 0;
 }

int operate(int a,int theta,int b)
{ switch(theta)
   {case '+':return(a+b);
    case '-':return(a-b);
    case '*':return(a*b);
    case '/':return(a/b);
   }
}

int val(char ch)
{ return (ch-'0');
}

int evaluteexpression()
 { sqstack opnd,optr;
   int ch,x,curint,theta,a,b;
   initstack(&optr);
   initstack(&opnd);
   push(&optr,'#');
   ch=getche();
   while (ch!='#' ||gettop(optr)!='#')
   { if (!valid(ch,validchar)) ch=getche(); //去掉非法字符
     else
      if (!in(ch,s_operator))//ch为操作数,则压栈
       { curint=0;
         while(valid(ch,validchar)&&!in(ch,s_operator))
   	 {curint=10*curint+val(ch);
	  ch=getche();
          }
	  push(&opnd,curint);}
      else
       {switch(precede(gettop(optr),ch))
	 {case '<': push(&optr,ch);ch=getche();break;
	  case '=': pop(&optr,&x);ch=getche();break;
	  case '>': pop(&optr,&theta);
		    pop(&opnd,&b);
		    pop(&opnd,&a);
		    push(&opnd,operate(a,theta,b));break;
	  case ' ':printf("
error");exit(1);
	}
       }
     }
     return gettop(opnd);
   }

void main()
{ int x;
  printf("
请输入一个算术表达式( 每个运算量只限输入整数据,且以#结束)
");
  x=evaluteexpression();
  printf("
该表达式的结果是:%d",x);
  }






3、	KMP算法
#include <stdio.h>
  #include <stdlib.h>
 #define maxstrlen 255      //用可以在255以内定义最大串长
 int next[7];
 typedef unsigned char SString[maxstrlen+1]; //0好单元可以存放串的长度
 void get_next(SString T) 
{      //求模式串T的next函数值并存入数组next。
      int i,j;
      i=1; next[1]=0; j=0;//
      while(i<T[0]){
	if(j==0||T[i]==T[j]) {++i;  ++j;  next[i]=j;}
	else j=next[j];
      }
      printf("
next[j] is:");
      for(i=1;i<=6;i++)
	 printf("%d",next[i]);

 }//get_next

 int index_kmp(SString S,SString T,int pos) {
      //利用模式串T的next函数求T在主串S中第pos个字符之后的位置
      //kmp算法。其中T非空,1<=pos<=strlength(s).
      int i,j;
      i=pos;j=1;
      while(i<=S[0]&&j<=T[0]) {
	if(j==0||S[i]==T[j]) {++i;++j;}
	else
	   j=next[j];
      }
      if(j>T[0]) return i-T[0];
      else
	 return 0;
 }//index_kmp

 void main()
 {
   SString S={17,'a','c','a','b','a','a','b','a','a','b','c','a','c','a','a','b','c'};
   SString T={6,'a','b','a','a','b','c'};
   //S[0]=17;   T[0]=6;
   get_next(T);
   printf("
it is :%d ",index_kmp(S,T,1));
 }




4. 稀疏矩阵的三元组顺序表

#define MAXSIZE  100  //假设非零元个数的最大值为100
#define ROW 7
#define COL 7
#define OK  1
#define FALSE 0

#include "stdlib.h"
#include "stdio.h"
#include "conio.h"

int a[ROW][COL]={{0,12,9,0,0,0,0}, {0,0,0,0,0,0,0}, {-3,0,0,0,0,14,0},
	         {0,0,24,0,0,0,0}, {0,18,0,0,0,0,0}, {15,0,0,-7,0,0,0}, {0,0,0,0,0,0,-5}};

typedef int ElemType;
typedef int Status;

typedef  struct{
  int  i,j;      //该非零元的行下标和列下标
  ElemType  e;
   }Triple;

typedef  union{
    Triple data[MAXSIZE+1];      //非零元三元组表,  data[0]未用
    int mu,nu,tu;                //矩阵的行数、列数和非零元个数
   }TSMatrix;

void InitTSMatrix(TSMatrix &T)
{ T.tu=0;
  }

Status ChangeArrayToMS(int a[][COL],TSMatrix &T)
{ int i,j,k=0;
  for(i=0;i<ROW;i++)
  for(j=0;j<COL;j++)
    if (a[i][j])
       {++k;
	T.data[k].i=i+1;T.data[k].j=j+1;T.data[k].e=a[i][j];
       }

  T.mu=ROW;T.nu=COL;T.tu=k;
  return OK;
}

void PrintTSmatrix(TSMatrix T)
{ //以三元组格式输出稀疏矩阵
 int k;
 if(T.tu>0)
  { printf("
 row   col   val
");
    printf("------------------
");
    for(k=1;k<=T.tu;k++)
       printf("(%4d%5d%5d)
",T.data[k].i,T.data[k].j,T.data[k].e);
  }
 }
 
Status TransposeSMatrix(TSMatrix M, TSMatrix &T) {
//采用三元组表存储表示,稀疏矩阵M的转置T
int q,p,col;
T.mu=M.nu;T.nu=M.mu;T.tu =M.tu;
if(T.tu) {
  q = 1;
  for (col=1 ;col<=M.nu; ++col)
  for (p=1; p<=M.tu; ++p)
  if (M.data[p].j==col){
      T.data[q].i=M.data[p].j ; T.data[q].j=M.data[p].i;
      T.data[q].e=M.data[p].e; ++q;}
  }     
  return OK;
} // TrazlsposeSMatrix

Status FastTransposeSMatrix(TSMatrix M, TSMatrix &T){
//采用三元组表存储表示,稀疏矩阵M的转置T(快速转换)
 int t,col,p,q,num[COL+1],cpot[COL+1];
 T.mu=M.nu;T.nu=M.mu;T.tu= M.tu;
if(T.tu) {
  for (col = 1; col<= M.mu;++col) num[col] = 0;
  for (t=1;t<=M.tu;++t)  ++num[M.data[t].j]; //求M中每一列含非0元素的个数
  cpot[ 1 ] = 1 ;
  // 求第 col列中第一个非0元素在 b. data 中的序号
  for (col = 2;col<= M.nu; ++col) cpot[col]=cpot[col-1] + num[col-1];
  for (p=1; p<=M.tu;++p)
  { col=M.data[p].j;q=cpot[col];
    T. data[q].i=M.data[p].j; T.data[q].j=M.data[p].i;
    T. data[q].e=M.data[p].e; ++cpot[col];
  }
}
 return OK ;
} // FastTransposeSMatrix

Status AddTSMatrix(TSMatrix A,TSMatrix B,TSMatrix &C)
{ //A+B==>C 两个稀疏矩阵相加结果存于C中
  //此算法类似于顺序表的归并算法
 int p,q,k;
 p=q=k=1;
 if (A.mu!=B.mu||A.nu!=B.nu)
   return FALSE;
 if(A.tu==0&&B.tu==0) {C.tu=0;return OK;}
 C.mu=A.mu;C.nu=A.nu;
 while(p<=A.tu&&q<=B.tu)
  {if ((A.data[p].i==B.data[q].i)&&(A.data[p].j==B.data[q].j))
    { if (A.data[p].e+B.data[q].e)
       { C.data[k].i=B.data[q].i;C.data[k].j=B.data[q].j;
	 C.data[k].e=A.data[q].e+B.data[q].e;
       }
      p++;q++;k++;
    }
   else if((A.data[p].i>B.data[q].i)||
            ((A.data[p].i==B.data[q].i)&&(A.data[p].j>B.data[q].j)))
         {C.data[k].i=B.data[q].i;C.data[k].j=B.data[q].j;
	  C.data[k].e=B.data[q].e;q++;k++;}
         else 
	 {C.data[k].i=A.data[p].i;C.data[k].j=A.data[p].j;
	  C.data[k].e=A.data[p].e;p++;k++;}
   }
  while (p<=A.tu)
    {C.data[k].i=A.data[p].i;C.data[k].j=A.data[p].j;
      C.data[k].e=A.data[p].e;p++;k++;}
  while (q<=B.tu)
    {C.data[k].i=B.data[q].i;C.data[k].j=B.data[q].j;
      C.data[k].e=B.data[q].e;q++;k++;}
   C.tu=k-1;
   return OK;
  }

 
void main()
{ TSMatrix T,T1,T2;
  InitTSMatrix(T);getch();
  ChangeArrayToMS(a,T);
  PrintTSmatrix(T);getch();
  TransposeSMatrix(T,T1);
  PrintTSmatrix(T1);getch();
  FastTransposeSMatrix(T,T1);
  PrintTSmatrix(T1);getch();
  AddTSMatrix(T,T1,T2);
  PrintTSmatrix(T2);
  }

5.	 二叉树算法
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
#define stackinitsize 100
#define OK 1
#define ERROR 0
#define OVERFLOW -1

typedef int TElemType ;
typedef int Status;

       //一一一一一二叉树的二叉链表存储表示一一一一一
typedef struct  BiTNode{ 
     TElemType   data;
     struct  BiTNode  *lchild,*rchild;   //左右孩子指针
   }BiTnode,*SElemType,*BiTree;

typedef struct{
  //该堆栈的元素是指针类型的
  //base和top均是指向指针的指针
  SElemType *base;
  SElemType *top;
  int stacksize;
}sqstack;//堆栈结构

         //一一一一一基本操作的函数原型说明(部分)一一一一一
    Status CreateBitree(BiTree &T);
        //按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树。
        //构造二叉链表表示的二叉树T.
    Status  PreOrderTraverse(BiTree T,Status(*Visit)(TElemType e));
        //采用二叉链表存储结构,visit是对结点操作的应用函数。
        //先序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
        //一旦visit()失败,则操作失败。
    Status  InorderTraverse(BiTree T,Status(*Visit)(TElemType e));
        //采用二叉链表存储结构,Visit是对结点操作的应用函数。
        //中序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
        //一旦visit()失败,则操作失败。
    Status  PostorderTraverse(BiTree T,Status(*Visit)(TElemType e));
        //采用二叉链表存储结构,visit是对结点操作的应用函数。
        //后序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
        //一旦visit()失败,则操作失败。
    Status  LevelIOrderTraverse(BiTree T,Status(*Visit)(TElemType e));
        //采用二又链表存储结构,Visit是对结点操作的应用函数。
        //层序遍历二叉树T,对每个结点调用函数Visit一次且仅一次。
	//一旦visit()失败,则操作失败



 sqstack *InitStack()//初始化堆栈
 {sqstack *s;
  s->base=(SElemType*)malloc(100*sizeof(SElemType));
  if(!s->base) return NULL;
  s->top=s->base;
  s->stacksize=100;
  return s;
 }

int StackEmpty(sqstack *s) //栈空判别
 {return(s->top==s->base);
 }

void Pop(sqstack *s,SElemType &e)//弹栈
 {
   e=*--s->top;
 }

Status GetTop(sqstack *s,SElemType &e)
 { 
   if(s->top==s->base) return ERROR;
   e=*(s->top-1);
   return OK;
 }

void Push(sqstack *s,SElemType e)//将元素压入堆栈
 {SElemType t;
  *s->top++=e;
 }


Status  CreateBiTree(BiTree &T){
    //按先序次序输入二叉树中结点的值(一个字符),空格字符表示空树。
    //构造二叉链表表示的二叉树T.
    char ch;
    ch=getche(); 
    if(ch==' ') T=NULL;
     else{
        if(!(T=(BiTNode *)malloc(sizeof(BiTNode)))) return(OVERFLOW);
        T->data=ch;             //生成根结点
        CreateBiTree(T->lchild);//构造左子树
        CreateBiTree(T->rchild);//构造右子树
    }
      return  OK;
    }//CreateBiTree

Status  PreOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
       //采用二叉链表存储结构,visit是对数据元素操作的应用函数,
       //先序遍历二叉树T的递归算法,对每个数据元素调用函数visit。
       //调用实例:  PreOrderTraverse(T,printElement);
   {
       if(T){
       if (Visit(T->data))
            if (PreOrderTraverse(T->lchild,Visit))
              if  (PreOrderTraverse(T->rchild,Visit)) return  OK;
            return  ERROR;
	}else  return  OK;
       }//preOrderTraVerse

Status InOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
       //采用二叉链表存储结构,visit是对数据元素操作的应用函数,
       //中序遍历二叉树T的递归算法,对每个数据元素调用函数visit。
   {
       if(T){
             if (InOrderTraverse(T->lchild,Visit))
	       if (Visit(T->data))
	         if (InOrderTraverse(T->rchild,Visit))   return  OK;
            return  ERROR;
	}else  return  OK;
       }//preOrderTraVerse

Status  PostOrderTraverse(BiTree T,Status(*Visit)(TElemType e))
       //采用二叉链表存储结构,visit是对数据元素操作的应用函数,
       //后序遍历二叉树T的递归算法,对每个数据元素调用函数visit。
   {
       if(T){
            if (PostOrderTraverse(T->lchild,Visit))
	      if  (PostOrderTraverse(T->rchild,Visit))
		if (Visit(T->data)) return  OK;
            return  ERROR;
	}else  return  OK;
       }//preOrderTraVerse


Status  PrintElement(TElemType  e)
       {   //输出元素e的值
           printf("%c",e);        
           return  OK;
	}

Status  InorderTraverseNoRecursion1(BiTree T,Status(*Visit)(TElemType e))
	        
    //采用二叉链表存储结构,visit是对数据元素操作的应用函数。
    //中序遍历二叉树T的非递归算法,对每个数据元素调用函数visit。
   {sqstack *s;
    BiTree p;
    s=InitStack();p=T; 
    while(p||!StackEmpty(s))
      {
        if(p){ Push(s,p);p=p->lchild;}//根指针进栈,遍历左子树
        else{       //根指针退栈,访问根结点,遍历右子树
	  Pop(s,p);if(!Visit(p->data))  return  ERROR;
	  p=p->rchild;
        }//else
      }//while
    return  OK;
  }//InorderTraVerse1

Status  InorderTraverseNoRecursion2(BiTree T,Status(*Visit)(TElemType e))
	        
    //采用二叉链表存储结构,visit是对数据元素操作的应用函数。
    //中序遍历二叉树T的非递归算法,对每个数据元素调用函数visit。
   {sqstack *s;
    BiTree p;
    s=InitStack();Push(s,T); 
    while(!StackEmpty(s))
      {
       while(GetTop(s,p)&&p) Push(s,p->lchild);//向左走到尽头
       Pop(s,p);                               //空指针退栈
       if(!StackEmpty(s)) {                    //访问结点,向右一步
	 Pop(s,p);if(!Visit(p->data))  return  ERROR;
	 Push(s,p->rchild);
       }//if
      }//while
    return  OK;
  }//InorderTraVerse1

void main()
{
  BiTree t;
    printf("
请按先序遍历输入二叉树(当左右子树为空时用空格输入)
");
  CreateBiTree(t);
  printf("
该二叉树的先序遍历为:
");
  PreOrderTraverse(t,PrintElement);
    printf("
该二叉树的中序遍历为:
");
  InOrderTraverse(t,PrintElement);
    printf("
该二叉树的后序遍历为:
");
  PostOrderTraverse(t,PrintElement); 
    printf("
该二叉树的中序遍历为:(用非递归调用1)
");
  InorderTraverseNoRecursion1(t,PrintElement);
    printf("
该二叉树的中序遍历为:(用非递归调用2)
");
  InorderTraverseNoRecursion2(t,PrintElement);
}




6、哈夫曼编码

#include "stdlib.h"
#include "stdio.h"
#include "conio.h"
#include "string.h"
#define ERROR 0;
#define OK 1;

typedef int Status ;

//哈夫曼树的存储和哈夫曼编码的存储
typedef struct{
      unsigned int weight;
      unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;       //动态分配数组存储哈夫曼树

typedef char **HuffmanCode; //动态分配数组存储哈夫曼编码表

Status Select(HuffmanTree HT,int n,int &s1,int &s2) {
  //在哈夫曼树HT[1..n] 搜索最大权值和最小权值并用s1,s2 返回它们的下标
  unsigned int temp=9999;
  int i;
  s1=0;s2=0;
  for(i=1;i<=n;i++) 
    if((HT[i].weight<temp)&&(HT[i].parent==0))
      {
        s1=i;temp=HT[i].weight;
      }
  temp=9999;
  for(i=1;i<=n;i++)
    if((HT[i].weight<temp)&&(HT[i].parent==0)&&(i!=s1))
      {
        s2=i;temp=HT[i].weight;
      }
  if((s1==0)&&(s2==0)) return ERROR;
  return OK;
}//select

  

 //求huffman编码的算法:
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int w[],int n)
{
  //w存放N个字符的权值(均?>0),构造hufmantree HT,并求N个字符有huffman编码HC
  HuffmanTree p;
  char *cd;
  int s1,s2,i,c,m,start,f;
  if(n<1) return ;
  m=2*n-1;                                       //哈夫曼树的结点数 
  HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));  //0号单元未用
    p=HT;p++;
    for(i=1;i<=n;++i)
      {
       p->weight=w[i-1];
       p->parent=0;
       p->lchild=0;
       p->rchild=0;
       p++;
      }//将各结点赋初值
    for(;i<=m;++i,++p)
      {
       p->weight=0;
       p->parent=0;
       p->lchild=0;
       p->rchild=0;
      }//后续结点赋初值
   
    for(i=n+1;i<=m;++i) 
   {  Select(HT,i-1,s1,s2);
      //在HT[1..i-1]选择parent为0且weight最小的两个结点,其序号为S1,S2
      //每次创建的树放在i的位置其中(i>n)
      HT[s1].parent=i;HT[s2].parent=i;
      HT[i].lchild=s1;HT[i].rchild=s2;
      HT[i].weight=HT[s1].weight+HT[s2].weight;
   }

  printf("
the huffmantree is:
");
  printf("     NO [weight  parent  lchild  rchild]
");
  printf("        --------------------------------
");
  for(i=1;i<=m;i++)
     printf("%6d [%6d,%6d,%6d,  %6d ]
",i,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);

  //从叶子到根逆向求每个字符的Huffman  编码
  HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
  cd=(char *)malloc(n*sizeof(char));
  cd[n-1]='';
  for(i=1;i<=n;++i)
  {  start=n-1;
     for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)
       if(HT[f].lchild==c)  cd[--start]='0';
       else  cd[--start]='1';
     HC[i]=(char*)malloc((n-start)*sizeof(char));
     strcpy(HC[i],&cd[start]);
  }
  free(cd);
}//end  huffmancoding

void main()
{
 HuffmanTree HT;
 int n,i,w[20];
 HuffmanCode HC;
 printf("please intput n=
");
 scanf("%d",&n);
 printf("please input w[%d]:
",n);
 for(i=0;i<n;i++)
    scanf("%d",&w[i]);
 HuffmanCoding(HT,HC,w,n);
 getch();
 printf("
the HuffmanCoding is:
");
 for(i=1;i<=n;i++)
  printf("%s
",HC[i]);

}




7、	最短路径的dijkstra算法
#include <stdio.h>
#define max 1000
#define n 6
typedef int Graph[n][n];
typedef int vertex;
void shortp(Graph G,vertex v,int dist[n])
{
  int i,wm,u,num=1,S[n];
  for(i=0;i<n;i++)
   {
     dist[i]=G[v][i];
     S[i]=0;/*数组dist及集合S赋初值*/
   }
  S[v]=1;  /*把顶点v加入集合S中*/

do{
   wm=max;
   u=v;
   for(i=0;i<n;i++)  /*选择顶点u*/
     if(S[i]==0)
      if(dist[i]<wm)
	{
	  u=i;
	  wm=dist[i];
	}
   S[u]=1;
   for(i=0;i<n;i++)
     if(S[i]==0)
       if(dist[u]+G[u][i]<dist[i])
	    dist[i]=dist[u]+G[u][i];
   num++;
   }while(num!=n-1);
}
void main()
  {
   Graph G;
   vertex v=0;
   int dist[n],i,j;
   printf("please input weight of Graph:
");
   for(i=0;i<n;i++)
     for(j=0;j<n;j++)
	scanf("%d",&G[i][j]);
   shortp(G,v,dist);
   for(i=0;i<n;i++)
     printf("the shortest path of v[%d]->v[%d] is:%d
",v,i,dist[i]);
  }



8、	普里姆算法求最小生成树
# include "alloc.h"
# include "conio.h"
# include "stdlib.h"
# include "stdio.h"
# include "limits.h"
//-------图的数组(邻接矩阵)存储表示--------
#define INFINITY INT_MAX            //整型最大值
#define MAX_VERTEX_NUM 20           //最大顶点个数
#define ERROR     0
#define OK        1
#define OVERFLOW -2

typedef struct{
 char v;
 int  i;
}VertexType;

typedef int VRType;
typedef int Status;

typedef enum{DG=0,DN=1,AG=2,AN=3}GraphKind; //{有向图、有向网、无向图、无向网}

typedef struct ArcCell{
   VRType adj;//VRType是定点关系类型。对无权图,用0和1
	      //表示相邻否。对待有权图,则表示权值类型
}ARcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct{
  VertexType  vexs[MAX_VERTEX_NUM]; //顶点向量
  AdjMatrix  arcs;                  //邻接矩阵
  int vexnum,arcnum;                //图的当前顶点数和弧数
  GraphKind kind;                   //图的种类标志
}MGraph;

struct {
       VertexType adjvex;  //顶点
       VRType lowcost;     //权值
}closedge[MAX_VERTEX_NUM]; //全局变量

Status CreateUDN(MGraph &G) {
  //采用数组(邻接矩阵)表示法,构造无相网G。
  int i,j,v1,v2,w,k;
  printf("
please input vexnum and arcnum:
");
  scanf("%d,%d",&G.vexnum,&G.arcnum);
  for(i=0;i<G.vexnum;++i)
     {G.vexs[i].v='v';G.vexs[i].i=i+1;}
  for(i=0;i<G.vexnum;i++)
     for(j=0;j<G.vexnum;j++)
	G.arcs[i][j].adj=INFINITY;
  for(k=0;k<G.arcnum;k++) {
     printf("
please input v1,v2,w:
");
     scanf("%d,%d,%d",&v1,&v2,&w);
     i=v1-1;j=v2-1;
     G.arcs[i][j].adj=w;
     G.arcs[j][i].adj=G.arcs[i][j].adj;
  }
  return OK;
}//CreateUND

Status CreateGraph(MGraph &G) {
       //采用数组表示法,构造图G
       return CreateUDN(G);
}//CreateGraph

int minimum(MGraph G){
  // min{closedge[vi].lowcost||closedge[vi].lowcost>0,vi in V-U}
  int i,k,min=INFINITY;
  printf("
 closedge:
");
  for(i=0;i<G.vexnum;++i)
     printf(" %d",closedge[i].lowcost);
  printf("
");
  for(i=0;i<G.vexnum;++i)
     if((closedge[i].lowcost)>0&&(closedge[i].lowcost<min))
	{
         k=i;min=closedge[i].lowcost;
	}
  return k;
}

void MinSpanTree_PRIM(MGraph G,VertexType u) {
   //用普里姆算法从第u个顶点出发构造网G的最小生成树T,输出T的各条边
   //记录从顶点u到V-u的代价最小的彼岸的辅助数组定义:
   //struct {
   //    VertexType adjvex;  //顶点
   //    VRType lowcost;     //权值
   //}closedge[MAX_VERTEX_NUM];
   int k,j,i;
   k=u.i-1;
   for(j=0;j<G.vexnum;++j)
      if(j!=k){
	  closedge[j].adjvex.v=u.v;
	  closedge[j].adjvex.i=u.i;
	  closedge[j].lowcost=G.arcs[k][j].adj;
      }//end for .辅助数组初始化
   closedge[k].lowcost=0;    //初始,U={u}
   for(i=1;i<G.vexnum;++i) { //选择其余G.vexnum-1个顶点
      k=minimum(G);
      printf("k=%d",k);
       //此时closedge[k].lowcost=
       //          min{closedge[vi].lowcost||closedge[vi].lowcost>0,vi in V-U}
      printf(" 
v%d-->v%d",closedge[k].adjvex.i,G.vexs[k].i);//输出生成树的边
      closedge[k].lowcost=0;
      for(j=0;j<=G.vexnum;++j)
	 if(G.arcs[k][j].adj<closedge[j].lowcost)
	     {
	      closedge[j].adjvex.i=G.vexs[k].i;
              closedge[j].lowcost=G.arcs[k][j].adj;
	     }
    }//end for
}//minispenTree


void main()
{
  MGraph G;
  VertexType u={'v',1};
  int i,j;
  CreateGraph(G);
  for(i=0;i<G.vexnum;i++)
  {
     printf("
");
     for(j=0;j<G.vexnum;j++)
       if (G.arcs[i][j].adj!=INFINITY)
	  printf(" %d ",G.arcs[i][j].adj);
       else
	  printf(" ∞");
   }
  MinSpanTree_PRIM(G,u);
}


9、五种排序算法
#include "stdio.h"
#include “conio.h”
#include "stdlib.h"
#include "math.h"
#include "dos.h"

#define Max 100
typedef int sqlist[Max+1];

void insertsort(sqlist a,int n)
{
  int i,j;
  for(i=2;i<=n;i++)
  {
    if(a[i]<a[i-1])
    {
      a[0]=a[i];
      for(j=i-1;a[0]<a[j];--j)
	 a[j+1]=a[j];
      a[j+1]=a[0];
     }
  }
}

void shellsort(sqlist r,int n)
{
  int i,j,gap,x;
  gap=n/2;
  while(gap>0)
   {
     for(i=gap+1;i<=n;i++)
      {
       j=i-gap;
       while(j>0)
	 if(r[j]>r[j+gap])
	   {
	    x=r[j];
	    r[j]=r[j+gap];
	    r[j+gap]=x;
	    j=j-gap;
	   }
	 else j=0;
      }
     gap=gap/2;
   }
}
void bubblesort(sqlist r,int n)
{
  int i,j,w;
  for(i=1;i<=n-1;i++)
    for(j=n;j>=i+1;j--)
       if(r[j]<r[j-1])
	{
	 w=r[j];
	 r[j]=r[j-1];
	 r[j-1]=w;
	}
}

void selectsort(sqlist r,int n)
{
 int i,j,k,temp;
 for(i=1;i<=n-1;i++)
   {
    k=i;
    for(j=i+1;j<=n;j++)
      if(r[j]<r[k]) k=j;
    temp=r[i];
    r[i]=r[k];
    r[k]=temp;
   }
}

int partion( sqlist a,int n,int low,int high)
{
  int p,i;
  p=a[low];
  a[0]=a[low];
  while(low<high)
    {
      while(low<high&&a[high]>=p)  --high;
      a[low]=a[high];
      while(low<high&&a[low]<=p) ++low;
      a[high]=a[low];
   }
  a[low]=a[0];
/* for(i=1;i<=n;i++)
    printf("%d ",a[i]);
  printf("

");*/
  return low;
}

void quicksort(sqlist a,int n,int low,int high)
{
  int p,i;
  if(low<high)
    {
      p=partion(a,n,low,high);
      quicksort(a,n,low,p-1);
      quicksort(a,n,p+1,high);
    }
}


 void main()
 {
  int i,n=10;
  char ch;
  sqlist a;
  for(i=1;i<=10;i++)
    a[i]=11-i;
  printf("

");
  printf("   ┌─────────────┐
");
  printf("   │      1---插入排序        │
");
  printf("   │      2---希尔排序        │
");
  printf("   │      3---冒泡排序        │
");
  printf("   │      4---选择排序        │
");
  printf("   │      5---快速排序        │
");
  printf("   │        请选择(1--5)      │
");
  printf("   └─────────────┘
");
  ch=getch();
  if(ch=='1')     {printf("插入排序的结果是:
");insertsort(a,n);}
  else if(ch=='2'){printf("希尔排序的结果是:
");shellsort(a,n);}
  else if(ch=='3'){printf("冒泡排序的结果是:
");bubblesort(a,n);}
  else if(ch=='4'){printf("选择排序的结果是:
");selectsort(a,n);}
  else if(ch=='5'){printf("快速排序的结果是:
");quicksort(a,n,1,n);}
  else printf("对不起,你选择的参数不对!");
  for(i=1;i<=10;i++)
    printf("%5d",a[i]);
 }

  

原文地址:https://www.cnblogs.com/wc1903036673/p/3413000.html