课程名称:计算机软件

使用软件:devcpp

注意:这里列出了关于单链表,二叉树,图,查找和排序的编程,全部程序由博主一人编写,会有瑕疵,谨慎使用。

1.单链表

要求:(1)建立单向链表,表长任意;

(2)可交互输出单链表中的内容;

(3)编写算法计算出自己所建单链表的长度并输出;

(4)删除自己所建单链表中的第K个结点,并将剩余结点输出;

(5)将单链表倒排,输出结果。

程序:

#include <stdio.h> 
#include <stdlib.h>

//定义链表中的节点 
struct node
{  unsigned char data;//链表中的数据 
   struct node * next;//指向下一节点的指针 
};

//变量定义
struct node  *p,*p1,*p2,*head;

//函数声明
void ListCreate();
void ListTraverse();
void ListLength();
int ListDelete();
int ListReverse();

//主函数 
int main()
{
 ListCreate();        //单向链表的建立
 ListTraverse();      //单向链表的输出
 ListLength();        //单向链表长度计算
 ListDelete();        //单向链表结点的删除
 ListReverse();      //单链表的倒排 
}

//单向链表的建立
void ListCreate()
{   
    head=p=(struct node * )malloc(sizeof(struct node));
 printf("请输入链表数据元素值(0为结束标志,中间不能用任何符号):\n"); 
    scanf("%c",&p->data);//头结点的数据成员 
    while(p->data!='0')//给出0结束条件,退出循环
    {   
   p1=p; 
      p=(struct node * )malloc(sizeof(struct node)); 
      scanf("%c",&p->data);//中间结点数据成员
      p1->next=p;//中间结点的指针成员值
    } 
    p->next=NULL;//尾结点的指针成员值 
}

//单向链表的输出
void ListTraverse()

    p=head;
    printf("\n链表数据成员是:"); 
    while(p->next!=NULL) 
    { 
      printf("%c  ",p->data);  //输出成员数据
      p=p->next; 
    }   
}

//单向链表长度计算
void ListLength()
{
    p2=head->next;
    int  j=1;            //j用来存放链表的长度
    while((p2->data)-48)
    {
      p2=p2->next;
      j++;
    }
    printf("\n链表长度是:  %d",j);
}

//单向链表结点的删除
int ListDelete()
{
    p2 = head;

int j = 1,M,K;
   
    printf("\n要删除第几个节点: ");
 scanf("%d",&K);

if ( j > (K-1)) //删除头节点
   {
      struct node  *p3;
      p3=p2;
      p2=p3->next;
    }
    else   //删除其它节点
    {
    while ((p2->next)-48 && j < (K-1))
 {
        p2 = p2->next;
        ++j;
    }
     if (p2->next == NULL )
 {
        printf("Position Error\n");
        return 0;
    }
    struct node *temp = p2->next;  //执行删除操作
    p2->next = temp->next;
    }   
    p=head;
    printf("删除后的链表数据成员是:"); 
    while(p->next!=NULL) 
    { 
      printf("%c  ",p->data);  //输出成员数据
      p=p->next; 
    } 
}

//单链表的倒排
int ListReverse()
{
    struct node *h,*h1,*h2;
    h=head;
    h1=h;                    
    h=NULL;
    while(h1->next!=NULL)      //通过循环使h从最后一个元素依次向前
    { 
        h2 = h1->next; 
        h1->next = h; 
        h = h1; 
        h1 = h2;
    }  
    printf("\n倒排后的链表数据成员是:"); 
    while(h!=NULL)  //输出数据元素
    { 
      printf("%c  ",h->data); 
      h=h->next; 
    }  
}

难点:单链表的倒排,这里有两种方法实现

1)逆序单链表的循环算法:

 1 LINK_NODE *ReverseLink(LINK_NODE *head)2     {3         LINK_NODE *next;  4 LINK_NODE *prev = NULL;  5  6 while(head != NULL)  7  {  8 next = head->next;  9 head->next = prev; 10 prev = head; 11 head = next; 12  } 13 14 return prev; 15 }

2)逆序单链表的递归算法:

 1 LINK_NODE *ReverseLink2(LINK_NODE *head)2    {3         LINK_NODE *newHead;  4  5 if((head == NULL) || (head->next == NULL))  6 return head;  7  8 newHead = ReverseLink2(head->next); /*递归部分*/  9 head->next->next = head; /*回朔部分*/ 10 head->next = NULL; 11 12 return newHead; 13 }

循环还是递归?这是个问题。当面对一个问题的时候,不能一概认为哪种算法好,哪种不好,而是要根据问题的类型和规模作出选择。对于线性数据结构,比较适合用迭代循环方法,而对于树状数据结构,比如二叉树,递归方法则非常简洁优雅。原文链接:https://blog.csdn.net/lycnjupt/article/details/47103433

如果想了解关于逆序单链表的其它实现方法,可以查看链接:

http://blog.sina.com.cn/s/blog_68e4d2910100tc0i.html

2.二叉树

要求:(1)动态交互建立二叉树,结点个数任意;

(2)分别用DLR,LDR,LRD三种方式对二叉树进行遍历,并输出结果;

(3)计算二叉树中的结点个数并输出;

(4)计算二叉树的深度并输出。

我自己的程序:

#include <stdio.h>
#include <stdlib.h>

//节点声明,数据域、左指针、右指针
typedef struct BiTNode
{
   int data;//二叉树数据元素
   struct BiTNode *Left,*Right;//二叉树左右指针
}BiTNode,*BiTree;

//函数声明
int CreateBiTree(BiTNode **T);
void DLR_BiTree(BiTNode *T);
void LDR_BiTree(BiTNode *T);
void LRD_BiTree(BiTNode *T);
int BiTreeCount(BiTNode *T);
int BiTreeDeep(BiTNode *T);

//主函数
int main()
{
   BiTree T;
   int depth,Count = 0;
  
   printf("请输入第一个节点的值(0表示没有该节点): ");
   CreateBiTree(&T);//二叉树建立
   printf("\n");
  
   printf("先序遍历二叉树:");
   DLR_BiTree(T);//二叉树先序遍历
   printf("\n");
  
   printf("中序遍历二叉树:");
   LDR_BiTree(T);//二叉树中序遍历
   printf("\n");
  
   printf("后序遍历二叉树:");
   LRD_BiTree(T);//二叉树后序遍历
   printf("\n");
  
   Count = BiTreeCount(T);//求二叉树结点个数  
   printf("二叉树结点个数:%d\n",Count); 
  
   depth = BiTreeDeep(T);//求二叉树深度 
   printf("二叉树的深度为:%d\n",depth);
}

//先序创建二叉树 
int CreateBiTree(BiTNode **T) 

    int ch; 
    scanf("%d",&ch);//给二叉树第一个节点赋值 
    if (ch == 0) 
    { 
        *T = NULL;  //输入为0表示没有该节点
        return 0; 
    } 
    else 
    { 
        *T = (BiTNode *)malloc(sizeof(BiTNode));  //给二叉树节点分配内存
        if (T == NULL) 
        { 
            printf("failed\n"); 
            return 0; 
        } 
        else 
        { 
            (*T)->data = ch; 
            printf("输入%d的左子节点:",ch); 
            CreateBiTree(&((*T)->Left));  //递归给二叉树左节点赋值
            printf("输入%d的右子节点:",ch); 
            CreateBiTree((&(*T)->Right)); //递归给二叉树右节点赋值
        } 
    } 
 
    return 1; 
}

//二叉树先序遍历
void DLR_BiTree(BiTNode *T)
{
 if( T == NULL) return;//递归调用的结束条件
 printf("%d",T->data);//访问节点的数据域
 DLR_BiTree(T->Left);//先序递归遍历左子树
 DLR_BiTree(T->Right);//先序递归遍历右子树
}

//二叉树中序遍历
void LDR_BiTree(BiTNode *T)
{
 if(T==NULL) return;//递归调用的结束条件
 LDR_BiTree(T->Left);//中序递归遍历左子树
 printf("%d",T->data);//访问节点的数据域
 LDR_BiTree(T->Right);//中序递归遍历右子树
}

//二叉树后序遍历
void LRD_BiTree(BiTNode *T)
{
 if(T==NULL) return;//递归调用的结束条件
 LRD_BiTree(T->Left);//后序递归遍历左子树
 LRD_BiTree(T->Right);//后序递归遍历右子树
 printf("%d",T->data);//访问节点的数据域
}

//求二叉树结点个数
int BiTreeCount(BiTNode *T)
{
    if(T==NULL)
        return 0;//空二叉树结点数为0
    else                           
        return BiTreeCount(T->Left)+BiTreeCount(T->Right)+1;//左右子树结点总数加1
}
 
//求二叉树深度
int BiTreeDeep(BiTNode *T) 

    int deep = 0; 
    if (T != NULL) 
    { 
        int leftdeep = BiTreeDeep(T->Left);//递归得到左子树深度 
        int rightdeep = BiTreeDeep(T->Right);//递归得到右子树深度
        deep = leftdeep >= rightdeep?leftdeep+1:rightdeep+1;//比较得到二叉树深度 
    } 
 
    return deep; 
}

3.图

要求:(1)根据教材上算法,完成图的深度和广度优先遍历,要求任意给定起始点,输出结果。

(2)根据教材上算法,完成图的单元最短路径的算法,要求任意给定源点,输出结果。

程序:

#include <stdio.h>
#include <stdlib.h>#define MAXVEX  100                      //最大顶点数
#define INFINITY 65535                //用65535来代表无穷大  //定义访问标记
int visited[MAXVEX]={0};  //定义图结构体
typedef struct
{  char vexs[MAXVEX];                //顶点表  int  arc[MAXVEX][MAXVEX];         //邻接矩阵,可看作边  int  numVertexes, numEdges;       //图中当前的顶点数和边数
}Graph;   //辅助数组中的元素定义
typedef struct
{  int distance;  int path[MAXVEX];
}ArrayNode;//函数声明
void CreateGraph(Graph *g);
void DFS(Graph g,int v);
void BFS(Graph g,int v);
void SHORT(Graph *g,int from,int to);
void SHORT(Graph *g,int from,int to);//主函数
int main()
{Graph g;int i,from,to;printf("t为1-4,分别表示无向图、有向图、带权无向图、带权有向图\n");CreateGraph(&g);//创建图 printf("\n输入遍历起点: ");  scanf("%d",&i);  printf("\n深度优先搜索遍历:");DFS(g,i);//深度优先遍历函数 printf("NULL\n");printf("广度优先搜索遍历:"); BFS(g,i);//广度优先遍历函数 printf("NULL\n");printf("\nDijkstra算法单元最短路径:");printf("\n请输入起点和终点(中间用空格):");scanf("%d %d",&from,&to);SHORT(&g,from,to);//Dijkstra算法单元最短路径函数
}//创建图
void CreateGraph(Graph *g)
{    int i,j,k,w,t;  printf("输入顶点数,边数和t(中间用空格):");  scanf("%d %d %d", &(g->numVertexes), &(g->numEdges),&t);  printf("\n");  for(i=1;i<=g->numVertexes;i++)//通过循环输入顶点信息  {  getchar();  printf("输入第%d顶点信息vexs[%d]=",i,i);  scanf("%c",&(g->vexs[i]));  }  printf("\n");  for(i=1;i<=g->numVertexes;i++)  for(j=1;j<=g->numVertexes;j++)  if (t>2)    g->arc[i][j] = INFINITY;//区别是否带权值  else        g->arc[i][j]=0;   for(k=1;k<=g->numEdges;k++)//通过循环输入边的信息  {  printf("输入有联系的两个顶点(中间用空格):");  scanf("%d %d",&i,&j);  if(i>g->numVertexes ||j>g->numVertexes)  exit(0);  if(t>2)  {  printf("输入权值:");  scanf("%d",&w);  g->arc[i][j]=w;  if(t==3)  g->arc[j][i]=w;  }  else  {     g->arc[i][j]=1;  if (t==1)    g->arc[j][i]=1;  }  }  printf("\n");  printf("输出邻接矩阵:\n");  for(i=1;i<=g->numVertexes ;i++)  {  for(j=1;j<=g->numVertexes ;j++)  {  printf("%8d",g->arc[i][j]);  //输出邻接矩阵 /*if(t>2&&g->arc[i][j]==65535)  g->arc[i][j]=0;  else if(t>2&&g->arc[i][j]!=65535)  g->arc[i][j]=1; */ }  printf("\n");  }
}  //深度优先遍历
void DFS(Graph g,int v)
{int j;  printf("%d->",v);         //输出访问顶点  visited[v]=1;            //全局数组访问标记置1表示已经访问  for(j=1; j<=g.numVertexes; j++)  if ((g.arc[v][j]!=0)&&(g.arc[v][j]!=65535)&&(!visited[j]))  DFS (g,j);//递归访问非0非无穷顶点
} //广度优先遍历
void BFS(Graph g,int v)
{int  q[g.numVertexes+1] ;  int  i,f,r,j ;for(i=0;i<g.numVertexes;i++)visited[i]=0;  //重置访问标记 f=r=0 ;  printf("%d->",v);//输出第一个顶点  visited[v]=1 ;//标记已访问  r++;  q[r]=v;  while (f<r)  {    f++; v=q[f];  for (j=1; j<=g.numVertexes; j++) //广度优先遍历依次访问与上一顶点有联系的点 {if ((g.arc[v][j]!=0)&&(g.arc[v][j]!=65535)&&(!visited[j]))  {       printf("%d->",j);//输出访问顶点 visited[j]=1 ;     r++; q[r]=j ;  }}  }
} //单元最短路径算法
void SHORT(Graph *g,int from,int to)
{int i,j,index=-1;  int n=1;//记录已经求出的两个点之间的最短距离的个数  ArrayNode shortestPath[MAXVEX];  int flag[MAXVEX]={0};//标记,为1表示到这个顶点的最短距离已求出  //1.求from到各个顶点的直接距离,即初始化shortestPath数组  for(i=1;i<=g->numVertexes;i++){  if(from==i){  shortestPath[i].distance=0;  shortestPath[i].path[0]=i;  flag[from]=1;  }  else if(g->arc[from][i]>0){  shortestPath[i].path[0]=from;  shortestPath[i].path[1]=i;  shortestPath[i].distance=g->arc[from][i];  }else shortestPath[i].distance=INFINITY;  }  //2.每次求一个最短路径  while(n<=g->numVertexes){  //选择shortestPath中距离最小的,求出from到这个顶点的最短路径  index=-1;  for(i=1;i<=g->numVertexes;i++){  if(i==from)  continue;  if(flag[i]==0 && index==-1 && shortestPath[i].distance!=INFINITY)  index=i;  if(flag[i]==0 && index!=-1 && shortestPath[i].distance<shortestPath[index].distance)  index=i;  }  flag[index]=1;  //修改到各个顶点的最短路径  for(i=1;i<=g->numVertexes;i++){  if(i==from)  continue;  if(g->arc[index][i]>0 && g->arc[index][i]+shortestPath[index].distance<shortestPath[i].distance){  shortestPath[i].distance=g->arc[index][i]+shortestPath[index].distance;  //修改路径  j=0;  while(1){  shortestPath[i].path[j]=shortestPath[index].path[j];  if(shortestPath[index].path[j]==index)  break;  j++;  }  shortestPath[i].path[j+1]=i;  }  }  n++;  }  //输出from到to的最短路径及长度  if(shortestPath[to].distance==INFINITY){  printf("%d到%d没有路径\n",from,to);  return;  }  printf("%d到%d的最短路径长度是:%d\n",from,to,shortestPath[to].distance);  printf("经过的顶点:  ");  i=0;  while(1){  printf("%-3d",shortestPath[to].path[i]);  if(shortestPath[to].path[i]==to)  break;  i++;  }  printf("\n");
}

4.查找和排序

要求:(1)任意给定无序序列,用对半检索法,交互检索任意给定的关键字KEY;

(2)任意给定无序序列,用快速排序法对序列进行排序,并统计交换次数;

(3)任意给定无序序列,用冒泡排序法对序列进行排序,并统计交换次数和排序趟数。

程序:

#include "stdio.h"
#define N 6//序列长度(可修改)//函数声明
int halfSort(int *b,int n);
void quickSort(int *b,int l,int r);
void bubbleSort(int *bb,int r);//全局变量定义
int o,p,k;
int KEY; //检索的关键字 //主函数
int main()
{int i,j,q;int a[100],aa[100],aaa[100];//以数组方式定义序列 printf("Hello World!\n");printf("\n1.请输入任意序列(用回车隔开)\n");for(i=1;i<=N;i++)scanf("%d",&a[i]);//输入无序序列 quickSort(a,1,N);//先排序再进行对半检索printf("排序后序列为:");for(j=1;j<=N;j++)printf("%d ",a[j]);//输出有序序列 printf("\n请输入需要检索的关键字KEY:"); scanf("%d ",&KEY);q=halfSort(a,N);//对半检索函数调用 printf("对半检索-关键字位置为:%d\n",q);printf("\n2.请输入任意序列(用回车隔开)\n");for(i=0;i<N;i++)scanf("%d",&aa[i]);//输入无序序列 quickSort(aa,0,N-1);//快速排序函数调用 printf("快速排序后序列为:");for(j=0;j<N;j++)printf("%d ",aa[j]);//输出有序序列 printf("\n交换次数为:%d\n",k);printf("\n3.请输入任意序列(用回车隔开)\n");for(i=0;i<N;i++)scanf("%d",&aaa[i]);//输入无序序列 bubbleSort(aaa,N);printf("冒泡排序后序列为:");//冒泡排序函数调用 for(j=0;j<N;j++)printf("%d ",aaa[j]);//输出有序序列 printf("\n交换次数为:%d\n",o);printf("排序趟数为:%d\n",p);return 0;
}//对半检索函数
int halfSort(int *b,int n)
{int high,mid,low;int rs=0;low=1;high=n;//初始状态 while(low<=high)//判断查找是否结束 {mid=(low+high)/2;if(KEY<b[mid]) high=mid-1;//关键字在前半区 elseif(KEY>b[mid]) low=mid+1;//关键字在后半区 else {rs=mid;break;}}return rs;
}//快速排序函数
void quickSort(int *bb,int l,int r)
{int m,n;int temp;if(l>=r) return;//只有一个记录或无记录,无须排序 m=l;n=r;temp=bb[m];while(m!=n)//寻找temp的最终位置 {while((bb[n]>=temp)&&(n>m))n--;//从右向左扫描,查找第一个小于temp的记录 if(m<n){bb[m++]=bb[n];k++;}while((bb[m]<=temp)&&(n>m))m++;//从左向右扫描,查找第一个大于temp的记录 if(m<n){bb[n--]=bb[m];k++;}}bb[m]=temp;//找到temp的最终位置 quickSort(bb,l,m-1);//递归处理左区间 quickSort(bb,m+1,r);//递归处理右区间
}//冒泡排序函数
void bubbleSort(int *bbb,int r)
{int m,n,noswap;int temp;for(m=0;m<(r-1);m++)//外循环,做N-1次起泡 {noswap=1;for(n=0;n<(r-m-1);n++)//内循环,置交换标志 if(bbb[n+1]<bbb[n])//比较 {temp=bbb[n];bbb[n]=bbb[n+1];bbb[n+1]=temp;//交换 o++;noswap=0;}if(noswap) break;//本趟起泡未发生记录交换,算法结束 p++;}
}

  

转载于:https://www.cnblogs.com/BoBoRing/p/8886094.html

关于单链表,二叉树,图,查找和排序的软件编程相关推荐

  1. c语言单链表的按序号查找,以下为单链表按序号查找的运算,分析算法,请在______处填上正确的语句。 pointer find_lklist(1kl...

    以下为单链表按序号查找的运算,分析算法,请在______处填上正确的语句. pointer find_lklist(1kl 更多相关问题 [单选题]Struts2框架最先加载的配置文件是: A. de ...

  2. python链表删除尾部节点_python单链表中如何查找和删除节点?

    在之前的文章[python单链表中如何插入和输出节点?]中给大家介绍了单链表是什么,以及如何进行添加节点.输出所以节点.下面本篇文章给大家介绍如何查找和删除节点,希望对大家有所帮助. 如何从单链表中查 ...

  3. 单链表的顺序查找c语言,单链表(C语言)

    首先 顺序存储在左侧,链式存储在右侧 在使用数组实现序列表之前,先对序列表的优缺点进行总结,因为它易于查找,添加和删除都很复杂. 回顾线性表顺序存储的优缺点 可以说链表的特性恰好相反,易于添加和删除, ...

  4. 单链表的基本操作-查找

    [问题描述] 实现有头结点单链表查找算法:根据关键字值查找其在单链表中的位置(第一次出现的位置). [输入形式] 第一行输入整数n(n不大于1000),表示单链表长度: 第二行输入若干个整数(以非法整 ...

  5. C语言版单链表:按序号查找结点值和按值查找表结点的代码总结

    先上函数模块 按序号查找结点 //按序号查找结点 LNode *GetElem(LinkList L,int i){int j=1;LNode *p=L->next;if(i==0)return ...

  6. c语言单链表递增排序,单链表 基本操作(元素递增排序)

    题目描述: 有一个带头节点的单链表L(至少有一个数据节点),设计一个算法使其元素递增有序排列. 解题思路: 由于单链表L中有一个以上的数据节点,首先构造一个只含有头结点和首节点的有序单链表(只含有一个 ...

  7. 字符串的冒泡排序c语言,c语言单链表冒泡排序_c语言字符串排序冒泡法_c语言链表排序...

    1. #include 2. 3. struct Node; 4. 5. typedef struct Node *PtrToNode; 6. typedef PtrToNode List; 7. t ...

  8. 【玩转链表①】单链表动图图解(超详解)

    学习导航 一.前言 二.快速入门链表 ①漫画图解 ②与顺序表的区别 三.链表接口的实现 ①准备函数 ②尾插和头插 ③头删和尾删 ④查找 ⑤向后插入向后删除 ⑥向前插入向前删除 ⑦向前插入pos节点处删 ...

  9. 【数据结构与算法】 01 链表 (单链表、双向链表、循环链表、块状链表、头结点、链表反转与排序、约瑟夫环问题)

    一.线性表 1.1 概念与特点 1.2 线性表的存储结构 1.3 常见操作 1.4 应用场景 二.链表 2.1 链表简介 2.2 单向链表(单链表) 2.21 基本概念 2.22 单链表基本操作 2. ...

最新文章

  1. centos6 升级gcc / 无法识别的命令行选项“-std=gnu++1y”的解决办法
  2. 如何恢复Windows“消失”的磁盘分区
  3. 【观点】从曾成杰案看民间金融的高风险与银行缺失的机制创新
  4. vue.js koa2 mysql_nodejs-koa2-mysql-sequelize-jwt
  5. 昨天购入mac mini一台,4688元港币
  6. EXCEL统计不重复值的数量
  7. mysql count 条件_MySQL的COUNT语句,竟然都能被面试官虐的这么惨?
  8. caffe训练过程中的可视化
  9. $$a,PHP独有的可变变量
  10. Apache配置访问控制、禁用php解析、rewrite伪静态、限定user_agent
  11. linux系统中归档管理器,深度商店应用归档管理器、KShutdown、7-Zip、California
  12. WSUS服务器点击报告报错解决办法
  13. java写入文件中文乱码问题_解决Java写入UTF-8文件中文乱码问题
  14. 数据科学家的一天,是怎样度过的?
  15. 大写字母与小写字母的转换
  16. JavaScript 鼠标移入移出状态(onmouseover、onmouseout)
  17. cdoj1087 基爷的中位数 二分
  18. Python——函数返回值
  19. 四、SSL 虚拟私有网络
  20. SqlMDF数据提取工具

热门文章

  1. 读C#开发实战1200例子记录-2017年8月14日10:03:55
  2. python之collections之有序字典(OrderedDict)
  3. 灵动标签调用友情链接
  4. Android API中被忽略的几个函数接口
  5. 通过扩展方法,将C#的DateTime(日期)转换成人性化的显示
  6. MySQL基础部分总结
  7. 10款中小企业必备的开源免费安全工具
  8. 云计算时代企业内部IT人员的新定位
  9. 深入浅出分布式文件系统MogileFS集群
  10. Linux管理磁盘配额