C语言与算法设计技能培训

 
C 语言与算法设计技能培训
1 用C语言实现下列各种排序:冒泡排序、选择排序、快速排序冒泡排序函数如下:
/*n表示待排序的数据的个数*/
#define     n 10
void    maopao(int a[])
{int i,j,temp;
 for(i=0;i<n-1;++i)
 {
   for( j=0;j<n-i;++j)
    if(a[j]>a[j+1])
    {temp=a[j];a[j]=a[j+1];a[j+1]=temp;}
 }
}
/*选择排序*/
void xuanze(int a[n])
{int i,j,temp,k;
 for(i=0;i<n-1;++i)
   {k=i;
     for(j=i+1;j<n;++j)
     if(a[k]<a[j])
      k=j;
      if(k!=i){temp=a[i];a[i]=a[k];a[k]=temp;}
    }
 }
 /*快速排序*/
 int part(int a[n],int low,int high)
 {int x;
   x=a[low];
   while(low<high)
     {
      while(low<high&&a[high]>=x)
       --high;
       a[low]=a[high];
      while(low<high&&a[low]<=x)
       ++low;
       a[high]=a[low];
      }
    a[low]=x;
    return low;
 }
 void Qsort(int a[n],int low,int high)
 {int pivotloc;
 if(low<high)
   { pivotloc=part(a,low,high);
     Qsort(a,low,pivotloc-1);
     Qsort(a,pivotloc+1,high);
    }
 }
main()
{
 int a[n],j;
 for(j=0;j<n;++j)
  scanf("%d",&a[j]);
   maopao(a);for(j=0;j<n;++j)
   printf("%5d",a[j]);
printf("/n");
   for(j=0;j<n;++j)
  scanf("%d",&a[j]);
   xuanze(a);for(j=0;j<n;++j)
   printf("%5d",a[j]);printf("/n");
   for(j=0;j<n;++j)
  scanf("%d",&a[j]);
   Qsort(a,0,n-1);for(j=0;j<n;++j)
   printf("%5d",a[j]);printf("/n");
 
      getch();
}
 
2、用C语言实现下列各种操作
1)        单链表的建立
2)        在第i个结点之前插入一个结点
3)        删除第i个结点
#define NULL 0
typedef struct node{
 int    data;
 struct node *next;
}node,*link;
/*单链表建立
void crealink(link *L,int n)
{link p,q;
 int i;
 *L=(link)malloc(sizeof(node));
 q=*L;
 
 q->next=NULL;
 for(i=1;i<=n;++i)
 {p=(link)malloc(sizeof(node));
   printf("input p->data=");
   scanf("%d",&p->data);
    p->next=NULL;
    q->next=p;
 q=p;
 }
 }
/*单链表的输出*/
void print(link L)
{link p;
 p=L->next;
 while(p)
 {printf("%5d",p->data);
 p=p->next;
 }
 printf("/n");
 }
/*在单链表的第I 个位置上插入元素值为e 的函数*/
void insert(link *L,int i,int e)
{link p,s;    int j=0;
 p=*L;
/*找被插入位置,p指向i-1位置*/
 while(p&&j<i-1)
 {p=p->next;++j;}
 if(!p||j>i)
 printf("error");
 else{
 /*申请结点*/
s= (link)malloc(sizeof(node));
 s->data=e;
 /*插入*/
 s->next=p->next;
 p->next=s;
 }
 }
/*删除单链表的第I 个位置上的元素值*/
void delink(link *L,int i)
{link p,s;    int j=0;
 p=*L;
 /*查找被删位置,p指向i-1位置*/
while(p&&j<i-1)
 {p=p->next;++j;}
 if(!p||j>i)
 printf("error");
 else{
 s=p->next;/S指向被删结点*/
 p->next=s->next;
 free(s);
 }
 }
   main()
{link L;
 int n,i,e;/*链表结点的个数*/
 printf("input link n=");
 scanf("%d",&n);
 crealink(&L,n);
 print(L);
 /*i表示被插位置*/
 printf("input i=");
 scanf("%d",&i);
   /*i表示被插值*/
 printf("input e=");
 scanf("%d",&e);
 insert(&L,i,e);
   print(L);
   /*i表示被删位置*/
 printf("input i");
 scanf("%d",&i);
   delink(&L,i);
    print(L);
 getch();
 }
 
3、用C语言实现下列各种操作
1)        二叉树的建立用递归法
2)        用递归方法对二叉树进行全序、中序、后序遍历及用非递归方法对树进行层次遍历
#define NULL 0
/*定义二叉树中的结点*/
typedef struct node
{char data;
struct node *lch,*rch;
}node,*link;
/*用先序遍历的思想建立二叉树*/
void creat(link *t)
{char ch;
scanf("%c",&ch);
if(ch=='0') *t=null;
else
{
*t=(link)malloc(sizeof(node));
(*t)->data=ch;
creat(&(*t)->lch);
creat(&(*t)->rch);
}
}
/*先序遍历函数*/
void preorder(link t)
{
if(t!=null)
{ printf("%c",t->data);/*访问根结点*/
inorder(t->lch);/* 先序遍历左子树*/
inorder(t->rch);/* 先序遍历右子树*/
}
}
 
/* 中序遍历函数*/
void inorder(link t)
{
if(t!=null)
{
inorder(t->lch);/* 中序遍历左子树*/
printf("%c",t->data); /*访问根结点*/
inorder(t->rch); /* 中序遍历右子树*/
}
}
/*后序遍历函数*/
void postorder(link t)
{
if(t!=null)
{
postorder(t->lch); /* 后序遍历左子树*/
postorder(t->rch); /*访问根结点*/
printf("%c",t->data); /*后序遍历右子树*/
}
}
 
/*二叉树的层次遍历*/
void lever(link t)
 { link    p;
/*定义空队列*/
bitree Q[100];
 int front=0,rear=0;
 /*初始化队列为空队列*/
Q[rear++]=t;
/*当队列为非空时*/
 while(front!=rear)
 { p=Q[front++];/*对头元素出队列*/
printf("%5d",p->data);
/*对头元素左孩子不空,将左孩子入队列*/
    if(p->lch!=NULL)
     Q[rear++]=p->lch;
   /*对头元素左孩子不空,将左孩子入队列*/
     if(p->rch!=NULL)
     Q[rear++]=p->rch;
   }
 }
 
main()
{
link t;
creat(&t);
prorder(t);
printf("/n");
inorder(t);
printf("/n");
postorder(t);
printf("/n");
lever(t);
printf("/n");
getch();
}
 
 
4、用C语言实现下列各种操作
1)        用邻接表法建立有向图的邻接表
2)        用深度优先和广度优先法来遍历该有向图
#define NULL 0
/*定义访问数组*/
int visited[100];
/*邻接点及顶点的定义*/
typedef struct node
{int adjvex;
struct node *next;}node;
/*顶点的定义*/
typedef struct
{int vex;
 node *firstadj;
}vertex;
/*邻接表的定义*/
typedef struct
{ vertex data[100];
 int      m ;/*m表示图中顶点的个数*/
} adjlist;
/*void creategraph(adjlist *g)
功能:建立有向图的邻接表,图中的边由键盘给出。
void dfs(adjlist    g)
功能:完成有向连通图的深度优先遍历。
void bfs(adjlist    g)
功能:完成有向连通图的广度优先遍历。
 有向图的邻接表的建立程序*/
void creategraph(adjlist *g)
{int    n,e; /*n表示图中的顶点个数,e表示边的条数*/
 int j,i,k;
 node *p,*q;
/*由键盘输入图的顶点个数及边的条数*/
 printf("input n=");
 scanf("%d",&n);
 printf("input e=");
 scanf("%d",&e);
/*初始化邻接表*/
 g->m=n;
 for(j=0;j<=n-1;++j)
 {g->data[j].firstadj=NULL;
 g->data[j].vex=j;
 }
for(j=0;j<e;++j)
{/*由键盘输入一对边*/
 printf("input i,k:");
 scanf ("%d%d",&i,&k);
/*申请一个邻结点*/
p=(node *)malloc(sizeof(node));
p->adjvex=k;
p->next=NULL;
if(g->data[i].firstadj==NULL)
g->data[i].firstadj=p;
else
{q=g->data[i].firstadj;
while(q->next)
q=q->next;
q->next=p;
}
}
}
/* 有向图的深度优先遍历*/
void dfs(adjlist g, int v )
{node *p;
 printf("%3d",v);
 visited[v]=1;
 p= g.data[v].firstadj;
 while(p)
{if(visited[p->adjvex]==0) dfs(g , p->adjvex);
 p=p->next;
 }
}
/*有向图的广度优先遍历程序*/
void bfs(adjlist g, int v )
{/*定义空队列*/
int Q[100];
int front=0,rear=0;
node *p;
visited[v]=1;
printf("%3d",v);
Q[rear++]=v;
while(front!=rear)
{v=Q[front++];
 p= g.data[v].firstadj;
 while(p)
 {if(visited[p->adjvex]==0)
    { visited[p->adjvex]=1;
      printf("%3d", p->adjvex);
      Q[rear++]= p->adjvex;
     }
   p=p->next;
 }
 }
}
/*主函数如下:*/
main()
{adjlist g;
 int    i;
 creategraph(&g);
/*初始化访问数组*/
for(i=0;i<g.m;++i) visited[i]=0;
dfs(g, 0);
printf("/n");
/*初始化访问数组*/
for(i=0;i<g.m;++i) visited[i]=0;
bfs(g , 0);
getch();
}
 
5、迷宫程序
#define    m   6
#define    n 9
void     path()
{/*定义迷宫并初始化迷宫*/
int maze[8][11]={1,1,1,1,1,1,1,1,1,1,1,
                  1,0,1,0,0,0,1,1,0,0,1,
                  1,1,0,0,0,1,1,0,1,1,1,
                   1,0,1,1,0,0,0,0,1,1,1,
                  1,1,1,0,1,1,1,1,0,1,1,
                  1,1,1,0,1,0,0,1,0,0,1,
                  1,0,0,1,1,1,0,1,1,0,1,
                  1,1,1,1,1,1,1,1,1,1,1}
 ;
 int    move[9][2];
/*定义栈*/
int    s[54][3];
 int  top=0;
int    i,j,k,p,f=0,g,h;
/*初始化增量矩阵*/
move[1][0]=-1; move[1][1]=0;
move[2][0]=-1; move[2][1]=1;
move[3][0]=0; move[3][1]=1;
move[4][0]=1; move[4][1]=1;
move[5][0]=1; move[5][1]=0;
move[6][0]=1; move[6][1]=-1;
move[7][0]=0; move[7][1]=-1;
move[8][0]=-1;move[8][1]=-1;
maze[1][1]=2;
 
 
/*初始化栈非空*/
 s[top][0]=1;
 s[top][1]=1;
 s[top][2]=3;
++top;
while (top!=0&&f==0)
{/*退栈*/
--top;
 i=s[top][0];
 j=s[top][1];
 k=s[top][2];
 /*当方向数小于8时*/
 while(k<=8)
 {/*试老鼠的下一位置*/
g=i+move[k][0];
 h=j+move[k][1];
 if (g==m&&h==n&&maze[g][h]==0)
 {for(p=0;p<top;++p)
 {
 printf("%d,%d,%d/n",s[p][0],s[p][1],s[p][2]);}
 printf("%d,%d,%d/n",i,j,k);
 printf("%d,%d,%d/n",m,n,k);
 f=1;
}
if(maze[g][h]==0)
{maze[g][h]=2;
/*下一位置可通,将上一位置入栈*/
s[top][0]=i;
s[top][1]=j;
s[top][2]=k;
++top;
/*改变老鼠的当前位置*/
i=g;
j=h;
k=0;
}
/*方向数增1*/
k=k+1;
}
}
if(f==0)
printf("no path/n");
}
main()
{
path();
getch();
}
 
6、约瑟夫问题程序
#define NULL 0
typedef struct QNode
{int data;
 struct QNode *next;
 }QNode,*linklist;
/*建立循环链表*/
void create(linklist *L,int    n)
{int i ;
 linklist    p,q;
 *L=(QNode*) malloc(sizeof(QNode));
 (*L)->next=NULL;
 q=*L;
 for(i=1;i<=n;++i)
 {p=(QNode*) malloc(sizeof (QNode));
 p->data=i;
 q->next=p;q=p;
}
q->next=(*L)->next; *L=(*L)->next;
}
/*输出循环链表*/
void print(linklist L)
{linklist p;
 p=L;
 while(p->next!=L)
 {printf("%5d",p->data);
 p=p->next;
 }
 printf("%5d",p->data);
 printf("/n");
 }
/*报数到第m号出圈*/
void    jone(linklist L,int m)
{linklist p,q; int i, j;
 p=L;
/*将指针定位到k-1号位*/
for(i=1;i<k;++i)
 p=p->next;
 /*从第k号位置开始报数,k报1号,k+1报2号,依次类推,将指针指向最后一个报数的人*/
 while(p->next!=p)
 {j=1;
 while(p->next!=p&&j<m-1)
{p=p->next;++j;}
q=p->next;
printf("%5d",q->data);
/*删除第m号*/
p->next=q->next;
p=p->next;
free(q);
}
printf("/nzuihou yige shi:%5d",p->data);
}
main()
{linklist L;
create(&L,100);
print(L);
jone(L,10);
getch();
}
 
7、Kruskal算法的设计
[ 实验目的]
1. 根据算法设计需要 , 掌握连通网的灵活表示方法;
2. 掌握最小生成树的Kruskal算法 ;
3. 基本掌握贪心算法的一般设计方法 ;
4. 进一步掌握集合的表示与操作算法的应用 .
[ 预习要求]
1. 认真阅读算法设计教材和数据结构教材内容 , 熟习连通网的不同表示方法和最小生成树算法;
2. 设计Kruskal算法实验程序 .
[ 参考数据类型或变量]
       typedef NodeNumber int; /* 节点编号 */
       typedef CostType int;     /* 成本值类型 */
typedef ElemType NodeNumber /* 实型或任意其它元素类型 */
       typedef struct { int ElemType; int tag; }NODE;
       typedef struct { CostType cost; NodeNumber node1, node2; }EDGE;
       NODE set[]={{1,-1},…,{n,-1}}; /* 节点集 , n为连通网的节点数 */
       EDGE es[ ]={{values of e1},…,{ values of em}}; /* 边集 , m为连通网的边数 */
       EDGE st[n-1]; /* 最小生成树的边集 */
[ 参考子程序接口与功能描述]
       int Find(NODE *set, ElemType elem)
       功能: 在数组set中顺序查找元素elem, 如果不成功, 返回-1; 否则, 使用带压缩规则的查找算法,返回所在子集的根节点索引.
       int Union(NODE *set, ElemType elem1, ElemType elem2)
功能: 应用Find算法首先找到elem1和elem2所在的子集, 然后应用带加权规则的并运算算法合并两个子集. 不成功时, 返回-1; 否则, 返回并集的根节点索引.
       void Sort(EDGE *es, int n)
功能: 用任意分类算法将连通图的边集按成本值的非降次序分类.
void Kruskal(EDGE *es, int m, NODE *set, int n, EDGE *st)
功能: 对有n个节点, m条边的连通网, 应用Kruskal算法生成最小生成树, 最小生成树的边存储在数组st中.
void Output(EDGE *st, int n)
功能: 输出最小生成树的各条边.
 
 [ 实验步骤]
1.     设计测试问题 ,修改并调试程序, 输出最小生成树的各条边, 直至正确为止 ;
2.     待各功能子程序调试完毕 , 去掉测试程序, 将你的程序整理成功能模块存盘备用.
[ 实验报告要求]
1.       阐述实验目的和实验内容 ;
2.       阐述Kruskal算法的原理方法;
3.       提交实验程序的功能模块 ;
4.       提供测试数据和相应的最小生成树 .
[ 思考与练习]
1.       设计由连通网初始边集数组生成最小堆的算法 ;
2.       设计输出堆顶元素 , 并将剩余元素调整成最小堆的算法;
3.       针对连通网初始边集最小堆表示 , 设计Kruskal算法;
4.       采用成本邻接矩阵表示连通网时 , 在剩余边中如何实现最小成本边的查找?
5.       采用成本邻接矩阵表示连通网时 , 用C语言实现Prim算法 .

8、 实验六   回溯算法设计
[ 实验目的]
1.       掌握回溯法解题的基本思想;
2.       掌握回溯算法的设计方法;
3.       针对子集和数问题,熟练掌握回溯递归算法、迭代算法的设计与实现。
[ 预习要求]
1.       认真阅读教材或参考书 , 掌握回溯法解题的基本思想, 算法的抽象控制策略;
2.       了解子集和数问题及解向量的定长和变长状态空间表示;
3.       针对解向量的定长表示 , 设计状态空间树节点扩展的规范(限界)函数及实现方法;
4.       分析深度优先扩展状态空间树节点或回溯的条件;
5.       分析和设计生成解向量各分量可选值的实现方法;
6.       设计和编制回溯算法的递归和迭代程序。
[ 参考数据类型或变量]
float s; // 表示有可能抵达答案节点的子路径上的元素之和;
float r; // 尚未测试的剩余集合元素之和;
float w[n]; // 存储原始集合的n个元素 , 根据问题实例初始化;
int x[n]; // 定长表示的解向量 , 各元素初始值为0;
[ 参考子程序接口与功能描述]
       void RecursiveSubset(float s, float r, int k)
       功能: 针对问题实例的递归回溯算法。
       void IterativeSubset(float s, float r, int k)
       功能: 针对问题实例的迭代回溯算法。
       void InitializeInstanse(void)
    功能 : 问题实例的初始化函数, 初始化子集和数M , w, x向量, s, r。
[ 实验步骤]
1.       录入、修改并测试你的程序,直至正确为止;
2.       针对问题实例,实录运行时的输入、输出界面;
3.       将你的程序和实录的界面存盘备用。
[ 实验报告要求]
1.       阐述实验目的和实验内容;
2.       提交模块化的实验程序源代码;
3.       简述程序的测试过程,提交实录的输入、输出界面;
4.       鼓励对实验内容展开讨论,鼓励提交思考与练习题的代码和测试结果。
[ 思考与练习]
1.       试针对解向量的变长表示设计回溯算法,上机测试正确性。
2.       试针对0/1背包问题设计回溯算法,比较与子集和数问题的算法差异。
 
 
 
 
 
 
 
 
 
 
 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值