数据结构典型算法的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]);
}
数据结构典型算法的VC实现(袁辉勇)的更多相关文章
- 在Object-C中学习数据结构与算法之排序算法
笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...
- javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例
栈(Stack)是限定仅在表尾进行插入或删除操作的线性表.表尾为栈顶(top),表头为栈底(bottom),不含元素的空表为空栈. 栈又称为后进先出(last in first out)的线性表. 堆 ...
- 数据结构与算法(c++)——跳跃表(skip list)
今天要介绍一个这样的数据结构: 单向链接 有序保存 支持添加.删除和检索操作 链表的元素查询接近线性时间 ——跳跃表 Skip List 一.普通链表 对于普通链接来说,越靠前的节点检索的时间花费越低 ...
- Java数据结构和算法(一)——简介
本系列博客我们将学习数据结构和算法,为什么要学习数据结构和算法,这里我举个简单的例子. 编程好比是一辆汽车,而数据结构和算法是汽车内部的变速箱.一个开车的人不懂变速箱的原理也是能开车的,同理一个不懂数 ...
- 数据结构与算法(C/C++版)【绪论/线性表】
声明:数据结构与算法系列博文参考了<天勤高分笔记>.<王道复习指导>.C语言中文网.非商业用途,仅为学习笔记总结! 第一章<绪论> 一.基本概念及入门常识 /// ...
- Java数据结构和算法 - 哈希表
Q: 如何快速地存取员工的信息? A: 假设现在要写一个程序,存取一个公司的员工记录,这个小公司大约有1000个员工,每个员工记录需要1024个字节的存储空间,因此整个数据库的大小约为1MB.一般的计 ...
- Python 数据结构和算法
阅读目录 什么是算法 算法效率衡量 算法分析 常见时间复杂度 Python内置类型性能分析 数据结构 顺序表 链表 栈 队列 双端队列 排序与搜索 冒泡排序 选择排序 插入排序 希尔排序 快速排序 归 ...
- Java数据结构和算法(七)B+ 树
Java数据结构和算法(七)B+ 树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 我们都知道二叉查找树的查找的时间复杂度是 ...
- Java数据结构和算法(一):简介
本系列博客我们将学习数据结构和算法,为什么要学习数据结构和算法,这里我举个简单的例子. 编程好比是一辆汽车,而数据结构和算法是汽车内部的变速箱.一个开车的人不懂变速箱的原理也是能开车的,同理一个不懂数 ...
随机推荐
- sqlserver 时间转换
sql server2000中使用convert来取得datetime数据类型样式(全) 日期数据格式的处理,两个示例: CONVERT(varchar(), 时间一, ) 结果:-- :/*时间一般 ...
- SDK Manager.exe 无法启动,一闪而过的解决办法
删掉 C:\Windows\system32\ 下的 java.exe.javaw.exe.javaws.exe 即可解决.(转载)
- 给sqlserver配置内存参数
操作环境:windows server 2003 R2 Enterprise Edition SP1 + 4G 内存 + Sqlsever 2005 在以上环境中,运行公司的ERP数据服务,sqlse ...
- Axis,axis2,Xfire以及cxf对比 (转)
Axis,axis2,Xfire以及cxf对比 http://ws.apache.org/axis/ http://axis.apache.org/axis2/java/core/ http:// ...
- 多线程 - 线程同步锁(lock、Monitor)
1. 前言 多线程编程的时候,我们不光希望两个线程间能够实现逻辑上的先后顺序运行,还希望两个不相关的线程在访问同一个资源的时候,同时只能有一个线程对资源进行操作,否则就会出现无法预知的结果. 比如,有 ...
- XE6 /XE8 & IOS开发之免证书真机调试三步走,生成iPA文件并安装到其它苹果设备上
XE6 & IOS开发之免证书真机调试(1):颁发属于自己的App签名证书(有图有真相) XE6 & IOS开发之免证书真机调试(2):连接真机并运行App(有图有真相) XE6 &a ...
- JS获取屏幕各种高
<script language="javascript"> var h = ""; h += " 网页可见区域宽:"+ doc ...
- maven+jetty项目在tomcat部署
步骤1:项目打包 clean install 步骤二:拷贝war 包到tomcat下 步骤三:修改server.xml文件的端口 步骤四:启动tomcat,注意jetty的项目是不需要带项目名的,To ...
- mem 族函数的实现
1.void * memcpy ( void * dest, const void * src, size_t num ); 头文件:#include <string.h>memcpy() ...
- 脚本学习python和linux-shell和jQuery(javascript)
使用脚本可以方便管理,使用计算机. 打算学脚本来更好地用计算机系统,特别是Linux. 学python因为它开源,而且是C家族的语言,本来也是课程需要,再加上它确实很好,所以非常主打,之前看过perl ...