C语言数据结构-实验

数据结构实验

  • 一元多项式
  • 哈夫曼编码和译码
  • 求图的最小生成树
  • 最短路径
  • 快速排序

具体是根据老师给的实验要求,其中部分代码由老师给出

一元多项式

C语言数据结构-实验_第1张图片

#include 
#include 
#include 

typedef struct polynode 
{ float coef; //系数
  int expn;   //指数
  struct  polynode *next;
}polynode,*polylist;


void poly_create(polylist &L)//创建链表
{
	int m;       //m为该多项式的项数
	polylist p;
	scanf("%d",&m);               //输入多项式的项数    
	L=(polylist)malloc(sizeof(polynode));
	p=L;
	for(int i=1;i<=m;i++) //循环输入系数和指数 i<=m(多项式的项数)
	{ 
	  p->next=(polylist)malloc(sizeof(polynode));
	  p=p->next;
	  scanf("%f %d",&p->coef,&p->expn);    //输入系数和指数
	}
	p->next=NULL;
}


void poly_display(polylist L) //显示链表的内容
{
	polylist p;
	p=L->next;
	printf("%.0fx(%d)",p->coef,p->expn);      
	p=p->next;
	while(p)
	{
		if(p->coef<0)
		{
			printf("%.0fx(%d)",p->coef,p->expn);//   %.0f[系数] X (%d)[指数]
		}     
		else
		{
			printf("+%.0fx(%d)",p->coef,p->expn);
		}   
	    p=p->next;
	}
	printf("\n");
}


void poly_add(polylist La,polylist Lb,polylist &Lc) //加法
{
	polylist pa,pb,pc;
	float x;
	pa=La->next; pb=Lb->next;
	pc=(polylist)malloc(sizeof(polynode));
	Lc=pc;
	while(pa&&pb)               
	{
		if(pa->expn==pb->expn)   //pa和pb的指数相同,即同类项
		{
			x=pa->coef+pb->coef; //同类项系数相加
			if(x!=0)             //系数相加后≠0
			{                       
				pc->next=(polylist)malloc(sizeof(polynode));
				pc=pc->next;
				pc->coef=x;
				pc->expn=pa->expn;
			}
			pa=pa->next; pb=pb->next;	
		}
		else  //无同类项时,把指数小的复制到C表
		{
			pc->next=(polylist)malloc(sizeof(polynode));
			pc=pc->next;
			if(pa->expn < pb->expn) //a的指数<b的指数
			{
				pc->coef=pa->coef;
				pc->expn=pa->expn;
				pa=pa->next;
			}
			else                    //a的指数≥b的指数
			{
				pc->coef=pb->coef;
				pc->expn=pb->expn;
				pb=pb->next;
			}
		}
	}
	while(pa) //还剩下a多项式
	{
		pc->next=(polylist)malloc(sizeof(polynode));
		pc=pc->next;
		pc->coef=pa->coef;
		pc->expn=pa->expn;
		pa=pa->next;
	}
	while(pb) //还剩下b多项式
	{	
		pc->next=(polylist)malloc(sizeof(polynode));
		pc=pc->next;
		pc->coef=pb->coef;
		pc->expn=pb->expn;
		pb=pb->next;
	}
	pc->next=NULL;
}


void poly_subtract(polylist La,polylist Lb,polylist &Lc) //减法
{
	polylist pa,pb,pc;
	float x;
	pa=La->next; pb=Lb->next;
	pc=(polylist)malloc(sizeof(polynode));
	Lc=pc;
	while(pa&&pb)
	{	
		if(pa->expn==pb->expn)
		{
			x=pa->coef - pb->coef;
			if(x!=0)
			{
				pc->next=(polylist)malloc(sizeof(polynode));
				pc=pc->next;
				pc->coef=x;
				pc->expn=pa->expn;
			}
			pa=pa->next; pb=pb->next;
		}
		else //无同类项时,指数小的复制到C表
		{
			pc->next=(polylist)malloc(sizeof(polynode));
			pc=pc->next;
			if(pa->expn < pb->expn) //a的指数小于b的指数
			{
				pc->coef=pa->coef;
				pc->expn=pa->expn;
				pa=pa->next;
			}
			else
			{
				pc->coef=-pb->coef; //-pb
				pc->expn=pb->expn;
				pb=pb->next;}
			}
		}
		while(pa) //还剩下a多项式
		{
			pc->next=(polylist)malloc(sizeof(polynode));
			pc=pc->next;
			pc->coef=pa->coef;
			pc->expn=pa->expn;
			pa=pa->next;
		}
		while(pb) //还剩下b多项式
		{
			pc->next=(polylist)malloc(sizeof(polynode));
			pc=pc->next;
			pc->coef=-pb->coef; //-pb
			pc->expn=pb->expn;
			pb=pb->next;
		}
		pc->next=NULL;
}


void main() //主函数
{
	polylist La,Lb,Lc,Ld;
	poly_create(La);
	poly_create(Lb);
	printf("一元多项式1:");
	poly_display(La);
	printf("一元多项式2:");
	poly_display(Lb);
	poly_add(La,Lb,Lc);
	printf("加的结果:");
	poly_display(Lc);
	poly_subtract(La,Lb,Ld);
	printf("减的结果:");
	poly_display(Ld);
	system("pause");//防止窗体闪退
}

运行结果:C语言数据结构-实验_第2张图片

哈夫曼编码和译码

C语言数据结构-实验_第3张图片

#include 
#include 
#include 
#include 

  typedef struct  
{
	char ch;                     //字母与编码
	int weight;                  //权重
	int parent,lchild,rchild;   //父亲与左右孩子
}HTNode,*HuffmanTree;
typedef char **HuffmanCode;
//以下为函数原型声明
  void	CreateHuffmanTree(HuffmanTree &HT,int w[],char ch[],int n); //构造HuffmanTree
  void	Select(HuffmanTree HT,int n, int &s1, int &s2); //选择两个权重最小的无父亲的结点
  void	HTCoding(HuffmanTree HT,HuffmanCode &HC,int n); //利用HuffmanTree对字符编码
  void	PrintCode(HuffmanCode HC,int n,char ch[]);//输出编码
  double	AverageLenght(HuffmanTree HT,HuffmanCode HC,int n); //求平均编码长度
  void	DeCode(HuffmanTree HT,int n);//解码

  
 void main()
  { 
	int n;	 //要输入的字母个数
    int i;   //变量i用来判断是否已经达到要输入的字母的数量  
	char arrch[20];     //数组存放输入的n个字母
	int arrweight[20];  //字母的权重
	double avlength;    //平均编码长度
	char ch;
	HuffmanTree HT; //HT是一个指针变量,用于指向HuffmanTree
	HuffmanCode HC; //HC是一个指针变量,用于存放对应字符的编码
	printf("字符的个数为:");
	scanf("%d",&n);//输入字符个数
	while((ch=getchar())!='\n');
	if(n>20||n<2)   exit(0); //输入的字符数超出要求范围,退出
	for(i=0;i<n;i++)  //输入字符和对应的权重
	{
		printf("请输入第%d个字符:",i+1);  //输入字母
		scanf("%c",&arrch[i]);              //输入字母
		printf("请输入第%d个字符的权重:",i+1);    //输入权重
		scanf("%d",&arrweight[i]);        //输入权重
		while((ch=getchar())!='\n');   //把回车读掉,防止回车变成第二组数据的字符
	}	
	//调用函数
	CreateHuffmanTree(HT,arrweight,arrch,n);//构造HuffmanTree
	HTCoding(HT,HC,n);//利用HuffmanTree对字符编码
	PrintCode(HC,n,arrch);  //输出编码
	avlength=AverageLenght(HT,HC,n);//求平均编码长度
	printf("平均编码长度为:%.2f\n",avlength);
	printf("要解码的数据:");
	DeCode(HT,n);//解码
	for(i=0;i<n;i++)
	free(HC[i]);
	free(HC);
	free(HT);
	system("pause");//窗体闪退
}//end_main

void CreateHuffmanTree(HuffmanTree &HT,int w[],char ch[],int n) 
{  // w存放n个字符的权值(均>0),构造哈夫曼树HT
	int i,m,s1,s2;
	m = 2 * n - 1;
	HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));  // 0号单元不用
	//设有一组权值存放于数组w[]中,对应的字符在数组ch[]中
	for (i=1; i<=n; i++) 
	{ 
		HT[i].weight=w[i-1];
		HT[i].parent=0;
		HT[i].lchild=0;
		HT[i].rchild=0;
        HT[i].ch = ch[i-1];
	}
	 //数组HT后n-1个元素先清空
	for (i=n+1; i<=m; i++) 
	{
		HT[i].weight=0;
		HT[i].parent=0;
		HT[i].lchild=0;
		HT[i].rchild=0;
		HT[i].ch='\0';
	}
	for (i=n+1; i<=m; i++) // 建哈夫曼树
	{  	Select(HT, i-1, s1, s2); //找出权重最小的两个结点,循环
		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;	 //构建结点的关系	 
	}	

} 

void Select(HuffmanTree HT,int  n, int &s1, int &s2) 
{//选择两个权重最小的无父亲的结点
	int i,j;                     //.PARENT=0
	int min;
	min=12345;
	for(i=1;i<=n;i++)  //n是输入字母的个数
	{
		if(HT[i].parent==0 && HT[i].weight<=min)
		{
			min=HT[i].weight;
			s1=i;      //找出第一个,并赋值给s1
		}
	}
	min=12345;
	for(j=1;j<=n;j++)
	{
		if(HT[j].parent==0 && HT[j].weight<=min && j!=s1)//j!=s1
		{
			min=HT[j].weight;
			s2=j;      //找出第二个,并赋值给s2 
		}
	}
}//end_Select

void HTCoding(HuffmanTree HT,HuffmanCode &HC,int n) 
{// 从叶子到根逆向求每个字符的哈夫曼编码
    int i,j,k, start;
	int f;
	int c;
    char * cd;
	HC=(HuffmanCode)malloc((n)*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-1]=(char *)malloc((n-start)*sizeof(char)); 
		for(j=start,k=0;j<n;j++,k++)// 从cd复制编码(串)到HC
			HC[i-1][k]=cd[j];
	}
	free(cd);   // 释放工作空间
}//end_HTCoding

void PrintCode(HuffmanCode HC,int n,char ch[]) 
{//输出编码     // n为字符的个数,ch为字母与编码
    printf("编码为:");
	for(int i=0;i<n;i++) 
	{  if(i!=0) printf("       ");  //输出格式
	   printf("%c  %s\n",ch[i],HC[i]);
   }
}//end_PrintCode



double AverageLenght(HuffmanTree HT,HuffmanCode HC,int n)
{//求平均编码长度   // n为字符的个数      
	int i,j;                   
	int a=0,b=0;          //a=总的权重,b=权重*路径长度
	double c;             // C为结果
	for(i=1;i<=n;i++)     //HC是一个指针变量,用于存放对应字符的编码
	{                     //HT是一个指针变量,用于指向HuffmanTree
		a=a+HT[i].weight; //计算总的权重
	}
	for(i=0,j=1;i<n;i++,j++) //[HT] j=1,0号单元不用
	{	
		(b=b + HT[j].weight*strlen(HC[i])); //权重 * 路径长度
	}
	c=((double)b*1.00)/(double)a;  //平均编码长度 = (权重*路径)/总的权重
	return c;
}//end_AverageLenght

void DeCode(HuffmanTree HT,int n)//解码
{
      int  i;      
	  char endflag='#';
	  char ch;
      i=2*n-1;            //从根结点开始往下搜索
	  scanf("%c",&ch);    //读入一个二进制码
      printf("对应的译码为:");
	  while (ch!=endflag)
      { 
		  if (ch=='0')   
			  i=HT[i].lchild;
           else  i=HT[i].rchild;

           if(HT[i].lchild==0) //tree[i]是叶子结点
		   {
			   printf("%c",HT[i].ch);  
			   i=2*n-1;
		   }
            scanf("%c",&ch);
      }
        if ((HT[i].lchild!=0) && (i!=2*n-1))  //电文读完但没到叶子结点
            printf("\n未能完全解码\n");
		printf("\n");
}//end_DeCode

运行结果:
C语言数据结构-实验_第4张图片

求图的最小生成树

C语言数据结构-实验_第5张图片

#include 
#include 

#define  INFINITY			65535		//最大值∞
#define  MAX_VERTEX_NUM		20          //最大顶点个数

typedef  struct 
{
	char    vexs[MAX_VERTEX_NUM];//顶点向量
	int		arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵
	int     vexnum, arcnum;//vexnum为顶点数
	                       //arcnum为边数	
 }MGraph;

typedef  struct 
{
     int	adjvex; //相关顶点下标
	 int	endvex; //所连接的路径的终点
     int   lowcost; //相关顶点间边的权值
}closedge[MAX_VERTEX_NUM];

void CreateUDN(MGraph &G) ;			//创建无向网络
int LocateVex(MGraph G, char v);	//结点在顶点向量中的下标
void PrintUDN(MGraph G);			//打印邻接矩阵
void MiniSpanTree_PRIM(MGraph G,closedge &minedge);//求最小生成树的算法
void PrintMinEdge(MGraph G,closedge minedge); //输出最小生成树的边


int main()
{	
	MGraph G;//定义一个图的变量
	closedge minedge;
	CreateUDN(G);//创建无向网络
	printf("该图的邻接矩阵存储示意图如下:\n");//
	PrintUDN(G);//打印邻接矩阵
	printf("\n");//
	MiniSpanTree_PRIM(G,minedge);//求最小生成树的算法
	printf("该图生成树的边如下:\n");//
	PrintMinEdge(G,minedge);//输出最小生成树的边
	printf("\n");//
	system("pause");//窗体闪退
	return 0;
	
}



void CreateUDN(MGraph &G) 
{//补充代码
	 int i,j,k,w; 
     char v1,v2,ch; 
     printf("网络的结点数为:");//
     scanf("%d",&G.vexnum); //输入结点数
     printf("网络的边数为:"); //
     scanf("%d",&G.arcnum); //输入边数
     printf("输入这%d个结点:",G.vexnum);// 
     while((ch=getchar())!='\n'); ///
     for(i=0;i<G.vexnum;i++) //输入所有的结点
	 { 
        scanf("%c",&G.vexs[i]); 
	 } 
     for(i=0;i<G.vexnum;i++) //邻接矩阵的值全都初始化为∞
	 { 
        for(j=0;j<G.vexnum;j++) 
		{ 
           G.arcs[i][j]=INFINITY; 
		} 
	 } 
     for(k=0;k<G.arcnum;k++) //输入边及权重
	 { 
        printf("请输入第%d条边及权重:",k+1); //
        while((ch=getchar())!='\n'); ///
        scanf("%c%c %d",&v1,&v2,&w); //输入边及其权重 
        i=LocateVex(G,v1); // i为结点v1在顶点向量中的下标
        j=LocateVex(G,v2); // j为结点v2在顶点向量中的下标
        G.arcs[i][j]=w;    // w为权重
        G.arcs[j][i]=w;    // w为权重
	 }               //↖无向图邻接矩阵关于对角线对称
     for(i=0;i<G.vexnum;i++) //让对角线的值都为0
	 { 
        G.arcs[i][i]=0; 
	 } 
} //End_CreateUDN



int LocateVex(MGraph G, char v)//返回结点在顶点向量中的下标
{//补充代码
     int i; 
     for(i=0;i<G.vexnum;i++) 
	 { 
        if(v==G.vexs[i]) 
		{ 
           return i; 
		} 
	 } 
}

void PrintUDN(MGraph G)  //输出存储结构示意图
{//补充代码	      
    int i,j; //循环变量i,j
    printf(" "); //
    for(i=0;i<G.vexnum;i++) //打印全部横的字母
	{ 
       printf("%6c",G.vexs[i]); 
	} 
    printf("\n"); //
    for(i=0;i<G.vexnum;i++) 
	{ 
       printf("%c",G.vexs[i]); //打印该行的首字母
       for(j=0;j<G.vexnum;j++) //打印邻接矩阵(权重)
	   { 
          //if(G.arcs[i][j]==65535) 
		  //{ 
            // printf(" ?"); 
		  //} 
          //else 
		  //{  
			 if(G.arcs[i][j]==65535) //权重为∞
			 {
				 printf("    ∞");
			 }
			 else //权重有值
			 {
			     //printf("∞");
                 printf("%6d",G.arcs[i][j]); 
			// }
		  } 
	   } 
       printf("\n"); 
	} 
} 




void MiniSpanTree_PRIM(MGraph G,closedge &minedge)  //求最小生成树的算法
{  
	int i,j,k,a;	
	int temp;
	int min;
	k=0;
	for(j=1; j<G.vexnum; ++j)//辅助数组初始化 
	{   
		minedge[j-1].adjvex=k; //下标   k=0 //顶点(邻接矩阵字母)
     	minedge[j-1].endvex=j; //所连接的路径的终点
		minedge[j-1].lowcost=G.arcs[k][j]; //权值
	}	
	for (i=0; i<G.vexnum-1; ++i) 
	{   
		min=minedge[i].lowcost;
	    k=i;
		for(j=i+1;j<G.vexnum-1;j++)//找出最小的边
		{
			if(minedge[j].lowcost < min)
			{  
			   min=minedge[j].lowcost;
			   k=j;
			}
        }				
		{  //第k个元素与第i个进行交换
		   temp=minedge[i].adjvex;
		   minedge[i].adjvex=minedge[k].adjvex;
		   minedge[k].adjvex=temp;
			
	       temp=minedge[i].endvex;
		   minedge[i].endvex=minedge[k].endvex;
		   minedge[k].endvex=temp;

		   temp=minedge[i].lowcost;
		   minedge[i].lowcost=minedge[k].lowcost;
		   minedge[k].lowcost=temp;
		}			
		for (j=i+1; j<G.vexnum-1; ++j)//a为找到的新顶点
		{
			a=minedge[i].endvex;
			k=minedge[j].endvex; 
			if(k!=a)
			{
				if(G.arcs[a][k] < minedge[j].lowcost) 
				{   
					minedge[j].adjvex=a;
					minedge[j].lowcost=G.arcs[a][k];
				}
			}
		}
	}	
}//MiniSpanTree



void PrintMinEdge(MGraph G,closedge minedge)  //输出最小生成树的边
{	//补充代码
    int i;//循环变量i
	for(i=0; i<G.vexnum-1; i++)
	{
		printf("%c%c  %d\n",G.vexs[minedge[i].adjvex],G.vexs[minedge[i].endvex],minedge[i].lowcost);
	}   //                        边的结点1              边的结点2                权值
}

运行结果:
C语言数据结构-实验_第6张图片

最短路径

C语言数据结构-实验_第7张图片

#include 
#include 

#define INFINITY 65535 // ∞
#define MAX_VERTEX_NUM 20 //最大顶点数 
#define MAX_ARCNUM_NUM 20 //最大边数 

typedef struct  //图的存储结构
{ 
   char vexs[MAX_VERTEX_NUM]; //一维数组:顶点
   int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //二维数组:邻接矩阵 
   int vexnum,arcnum; //vexnum为结点数  
}MGraph;              //arcnum为边数

typedef struct //栈的存储结构 
{ 
   int *base;//在栈构造之前和销毁之后,base的值为NULL 
   int *top;//栈顶指针 
   int stacksize;//当前已分配的存储空间 
}SqStack; 


void main() //主函数
{ 
   void CreateDN(MGraph &G); //创建有向网络 
   int LocateVex(MGraph G,char v); //结点在顶点向量中的下标 
   void ShortestPath(MGraph G,int v0,bool P[][MAX_VERTEX_NUM],int D[],int pre[]); //用迪杰斯特拉算法求最短路径 
   void PrintDN(MGraph G); //输出存储结构示意图 
   void PrintShortestPath(MGraph G,int a,bool P[][MAX_VERTEX_NUM],int D[],int pre[]); //输出最短路径 
   void InitStack(SqStack &S); //构造一个空栈 
   void Pop(SqStack &S,int &e); //弹出栈顶元素,用e返回
   void Push(SqStack &S,int e); //插入新的栈顶元素 
   int StackEmpty(SqStack S); //判断是否为空栈,若栈为空返回TRUE,不为空返回FALSE 
   
   int a; 
   char ch,v0; 
   int D[MAX_VERTEX_NUM]; 
   bool P[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; 
   int pre[MAX_VERTEX_NUM]; 
   
   MGraph G; //定义图
   CreateDN(G); //创建有向网络
   printf("\n该图的邻接矩阵为:\n"); //
   PrintDN(G); //输出存储结构示意图 
   printf("\n");  //
   printf("起点结点:"); // 
   while((ch=getchar())!='\n'); 
   scanf("%c",&v0);   //输入v0
   a=LocateVex(G,v0); //获取字符V0对应的下标a 
   ShortestPath(G,a,P,D,pre); //迪杰斯特拉最短路径算法 
   printf("该图最短路径如下:\n"); // 
   PrintShortestPath(G,a,P,D,pre); //输出最短路径
   printf("\n");  //
   system("pause");//窗体闪退
} 


/*-------------------------------------------------------------------------------------*/
void InitStack(SqStack &S) //构造一个空栈 
{ 
   S.base=(int*)malloc(30*sizeof(int)); //申请空间
   if(!S.base)   //申请失败
   {
	   exit(0);
   } 
   S.top=S.base; //空栈
   S.stacksize=30; //栈的大小为30
} 



int StackEmpty(SqStack S) //判断是否为空栈,若栈为空则返回TRUE,不为空则返回FALSE 
{ 
   if(S.base==S.top)   //为空栈
   { 
      return true; 
   } 
   else                //不为空栈
   { 
      return false; 
   } 
} 



void Push(SqStack &S,int e) //插入新的栈顶元素 
{ 
   if(S.top-S.base>=S.stacksize) //存储空间满
   { 
      S.base=(int*)realloc(S.base,(S.stacksize+100)*sizeof(int));//存储空间增加100 
      if(!S.base) //如果栈底为空
	  {
		 exit(0);
	  } 
      S.top=S.base+S.stacksize; //栈顶=栈底+空间
      S.stacksize+=100;//栈的容量增加100 
   } 
*S.top=e; //插入元素e
S.top++;  //栈顶+1
} 



void Pop(SqStack &S,int &e) //弹出栈顶元素,用e返回 
{ 
   if(S.top==S.base) //如果是空栈
   { 
      exit(0); 
   } 
S.top--;  //栈顶-1
e=*S.top; //记录元素
} 
/*-------------------------------------------------------------------------------------*/


int LocateVex(MGraph G,char v) //返回字母(结点)在有向边中的下标 
{ 
   int i; 
   for(i=0;i<G.vexnum;i++) 
   { 
      if(v==G.vexs[i]) 
	  { 
         return i; 
	  } 
   } 
} 



void CreateDN(MGraph &G) //创建有向网络 
{ 
   int i,j,k,w; //循环变量i,j,k  w为边的权重
   char v1,v2,ch; //v1,v2为一条边的两个结点
   
   printf("网络的结点数:");   //输入网络的结点数
   scanf("%d",&G.vexnum); 
   
   printf("网络的边数:");     //输入网络的边数
   scanf("%d",&G.arcnum); 
   
   printf("输入这%d个结点:",G.vexnum); //
   
   while((ch=getchar())!='\n'); //
   
   for(i=0;i<G.vexnum;i++)  //输入这几个结点 
   { 
      scanf("%c",&G.vexs[i]);   
   } 
   for(i=0;i<G.vexnum;i++)      //先定义邻接矩阵的值为∞
   { 
      for(j=0;j<G.vexnum;j++) 
	  { 
         G.arcs[i][j]=INFINITY; 
	  } 
   } 
   for(k=0;k<G.arcnum;k++)       //输入边的权重(邻接矩阵的值)
   { 
      printf("第%d条边及它的权重:",k+1); //
      while((ch=getchar())!='\n'); //
      scanf("%c%c %D",&v1,&v2,&w);  //输入有向边的两个结点及权重
      int i=LocateVex(G,v1);   //返回结点在矩阵中的下标
      int j=LocateVex(G,v2);   //返回结点在矩阵中的下标
      G.arcs[i][j]=w; 
   } 
   for(i=0;i<G.vexnum;i++) //让对角线的结点值为零
   { 
      G.arcs[i][i]=0; 
   } 
} 



void ShortestPath(MGraph G,int v0,bool P[][MAX_VERTEX_NUM],int D[],int pre[]) //用迪杰斯特拉算法求最短路径
{ 
   int i,w,v,min; 
   bool final[MAX_VERTEX_NUM]; 
   for(v=0;v<G.vexnum;v++) //初始化数据
   { 
      final[v]=false;     //全部定点初始化为未知最短路径状态
      D[v]=G.arcs[v0][v]; //将与v0点有连线的顶点加上权值
      pre[v]=-1;          //初始化为没有前驱
      for(w=0;w<G.vexnum;w++) 
	  { 
         P[v][w]=false; 
         if(D[v]<INFINITY) 
		 { 
            P[v][v0]=true; 
            P[v][v]=true; 
            pre[v]=v0; 
		 } 
	  } 
   } 
   D[v0]=0; 
   final[v0]=true; 
   pre[v0]=-1; 
   for(i=1;i<G.vexnum;i++) //开始主循环,每次求得v0到某个v顶点的最短路径
   { 
      min=INFINITY;  //当前所知离v0顶点的最近距离
      
	  for(w=0;w<G.vexnum;w++) //寻找离v0最近的顶点
	  { 
         if(!final[w]) 
		 { 
            if(D[w]<min) 
			{ 
               v=w; 
               min=D[w]; // w顶点离v0顶点更近
			} 
		 } 
	  } 
      
	  final[v]=true; //将目前找到的最近的顶点置为true
      
	  for(w=0;w<G.vexnum;w++) //修正当前最短路径及距离
	  { 
         if(!final[w] && (min+G.arcs[v][w]<D[w])) //如果经过v顶点的路径比现在这条路径的长度短的话
		 {  //说明找到了更短的路径,修改D、P数组
            D[w]=min+G.arcs[v][w]; 
            for(int i=0;i<G.vexnum;i++) 
			{ 
               P[w][i]=P[v][i]; 
			} 
            P[w][w]=true; 
            pre[w]=v; 
		 } 
	  } 
   
   } 

} 



void PrintDN(MGraph G) //打印邻接矩阵
{ 
   int i,j;  //循环变量i,j
   printf(" "); //
   for(i=0;i<G.vexnum;i++)     //打印横的字母
   { 
      printf("%4c",G.vexs[i]); 
   } 
   printf("\n"); //
   for(i=0;i<G.vexnum;i++)   //打印竖的字母及权重
   { 
      printf("%c",G.vexs[i]);  //打印每一行的第一个字母
      for(j=0;j<G.vexnum;j++)  //打印权重
	  { 
         if(G.arcs[i][j]==65535)  //权重为∞
		 { 
            printf("  ∞"); 
		 } 
         else   //权重有值
		 { 
            printf("%4d",G.arcs[i][j]); 
		 } 
	  } 
      printf("\n"); //打印完一行后换行
   } 
} 



void PrintShortestPath(MGraph G,int a,bool P[][MAX_VERTEX_NUM],int D[],int pre[]) //输出最短路径
{ 
   int i,j,e;  //循环变量
   SqStack S;  //定义栈S
   InitStack(S); //构造空栈S
   for(i=0;i<G.vexnum;i++) 
   { 
      if(pre[i]!=-1) //如果i的前驱存在 
	  { 
         j=i; 
         while(pre[j]!=-1) //不断地获取前驱,并入栈S中,直到前驱为空
		 { 
            Push(S,pre[j]); 
            j=pre[j]; 
		 } 
         while(!StackEmpty(S)) //若栈不为空,则为FALSE,把栈中的元素逐个输出 
		 { 
            Pop(S,e); 
            printf("%c->",G.vexs[e]); 
		 } 
         printf("%c",G.vexs[i]); //最短路径最后一个元素,没有->
         if(D[i]!=INFINITY) //输出路径的最短长度 
		 { 
            printf(" 长度是:%d\n",D[i]); 
		 } 
	  } 
      else if(i!=a) //如果i的前驱不存在并且i不是起点下标 
	  { 
         printf("%c->%c 无路径\n",G.vexs[a],G.vexs[i]); 
	  } 
   } 
} 

运行结果:
C语言数据结构-实验_第8张图片

快速排序

C语言数据结构-实验_第9张图片

#include 
#include
#include

#define MAXSIZE 20 

typedef struct //key
{ 
	int key; 
}KEY; 

typedef struct //线性表
{ 
	KEY r[MAXSIZE+1]; 
	int length; 
}SqList; 


/*----------------------------------------------------------------*///创建、打印线性表
void CreateSqList(SqList &L,int n) //创建线性表 
{  
	L.length=0; //初始化表长为0
	for(int i=1;i<=n;i++) 
	{ 
		scanf("%d",&L.r[i].key); //循环输入所有的数
		L.length++; //输入一个数,表长+1
	} 
}




void PrintSqList(SqList &L)//打印线性表
{ 
	for(int i=1;i<=L.length;i++) 
	{ 
		printf("%d ",L.r[i].key); 
	} 
} 
/*----------------------------------------------------------------*/


//交换顺序表L中子表的记录,使枢轴记录到位,并返回其所在位置
//此时在它之前(后)的记录均不大(小)于它
int Partition(SqList &L,int low,int high) //快速排序第一趟 
{ 
	int pivotkey; //枢轴
	pivotkey=L.r[low].key; //用子表的第一个记录作枢轴记录
	L.r[0]=L.r[low]; //初始化L.r[low]为表的第一个数
	while(low<high) //从表的两端交替向中间扫描
	{ 
		while(low<high && L.r[high].key>=pivotkey) 
		{ 
			high--; 
		} 
		L.r[low]=L.r[high]; //将比枢轴记录小的记录移到低端 
		while(low<high && L.r[low].key<=pivotkey) 
		{ 
			low++; 
		} 
		L.r[high]=L.r[low]; //将比枢轴记录大的记录移到高端 
	} 
	L.r[low]=L.r[0]; //L.r[low]重新初始化为表的第一个数
	return low; //返回枢轴所在位置
} 






//对顺序表L中的子序列L->r[low..high]作快速排序
void QSort(SqList &L,int low,int high) //对顺序表L中的子序列作快速排序 
{ 
	int pivoloc; //枢轴
	if(low<high) 
	{ 
		pivoloc=Partition(L,low,high); //将L->r[low..high]一分为二,算出枢轴值pivot
		QSort(L,low,pivoloc-1);  //对低子表递归排序
		QSort(L,pivoloc+1,high); //对高子表递归排序
	} 
}   /*    ↑
          ↑
          ↑
          ↑   */
void QuickSort(SqList &L) //对顺序表L作快速排序 
{ 
	QSort(L,1,L.length); 
} 


void main() //主函数 
{ 
	int a;  
	SqList L; //定义一个线性表L 
	printf("一共有几个数:"); // 
	scanf("%d",&a); //输入一共有几个数
	printf("输入要进行快速排序的这%d个数:\n",a); // 
	CreateSqList(L,a); //输入所有的数,用空格隔开
	QuickSort(L); //对线性表L作快速排序
	printf("快速排序后的结果为:\n"); //
	PrintSqList(L); //打印排序后的顺序表
	
	printf("\n");//
	system("pause");//窗体闪退
}

运行结果:
C语言数据结构-实验_第10张图片

你可能感兴趣的:(C语言,C语言,数据结构)