数据结构典型算法的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]); }