数据结构典型算法的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!\n");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!\n");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("\nNO.---------> x       y        direction\n");

	while(!stackEmpty(s))

	{

		pop(&s,&e);

		printf("%2d %10d%10d%10d\n",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!\n");//结果为1表明找到了出路

	else printf("I can't find the path!\n");//否则表明找不到出路,迷宫不可通行

}









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("\n");

 }





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("\nerror");exit(1);

	}

       }

     }

     return gettop(opnd);

   }



void main()

{ int x;

  printf("\n请输入一个算术表达式( 每个运算量只限输入整数据,且以#结束)\n");

  x=evaluteexpression();

  printf("\n该表达式的结果是:%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("\nnext[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("\nit 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("\n row   col   val\n");

    printf("------------------\n");

    for(k=1;k<=T.tu;k++)

       printf("(%4d%5d%5d)\n",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("\n请按先序遍历输入二叉树(当左右子树为空时用空格输入)\n");

  CreateBiTree(t);

  printf("\n该二叉树的先序遍历为:\n");

  PreOrderTraverse(t,PrintElement);

    printf("\n该二叉树的中序遍历为:\n");

  InOrderTraverse(t,PrintElement);

    printf("\n该二叉树的后序遍历为:\n");

  PostOrderTraverse(t,PrintElement); 

    printf("\n该二叉树的中序遍历为:(用非递归调用1)\n");

  InorderTraverseNoRecursion1(t,PrintElement);

    printf("\n该二叉树的中序遍历为:(用非递归调用2)\n");

  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("\nthe huffmantree is:\n");

  printf("     NO [weight  parent  lchild  rchild]\n");

  printf("        --------------------------------\n");

  for(i=1;i<=m;i++)

     printf("%6d [%6d,%6d,%6d,  %6d ]\n",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]='\0';

  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=\n");

 scanf("%d",&n);

 printf("please input w[%d]:\n",n);

 for(i=0;i<n;i++)

    scanf("%d",&w[i]);

 HuffmanCoding(HT,HC,w,n);

 getch();

 printf("\nthe HuffmanCoding is:\n");

 for(i=1;i<=n;i++)

  printf("%s\n",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:\n");

   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\n",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("\nplease input vexnum and arcnum:\n");

  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("\nplease input v1,v2,w:\n");

     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("\n closedge:\n");

  for(i=0;i<G.vexnum;++i)

     printf(" %d",closedge[i].lowcost);

  printf("\n");

  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(" \nv%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("\n");

     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("\n\n");*/

  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("\n\n");

  printf("   ┌─────────────┐\n");

  printf("   │      1---插入排序        │\n");

  printf("   │      2---希尔排序        │\n");

  printf("   │      3---冒泡排序        │\n");

  printf("   │      4---选择排序        │\n");

  printf("   │      5---快速排序        │\n");

  printf("   │        请选择(1--5)      │\n");

  printf("   └─────────────┘\n");

  ch=getch();

  if(ch=='1')     {printf("插入排序的结果是:\n");insertsort(a,n);}

  else if(ch=='2'){printf("希尔排序的结果是:\n");shellsort(a,n);}

  else if(ch=='3'){printf("冒泡排序的结果是:\n");bubblesort(a,n);}

  else if(ch=='4'){printf("选择排序的结果是:\n");selectsort(a,n);}

  else if(ch=='5'){printf("快速排序的结果是:\n");quicksort(a,n,1,n);}

  else printf("对不起,你选择的参数不对!");

  for(i=1;i<=10;i++)

    printf("%5d",a[i]);

 }

  

你可能感兴趣的:(数据结构)