数据结构的C语言实现-线性表的合并与排序

一、线性表简介:

1、线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列

2、线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储,但是把最后一个数据元素的尾指针指向了首位结点)

二、线性表的一般操作:

1InitList(& L)
        //构造一个空的线性表 2DestroyList(& L)
       //线性表存在了,消耗一个线性表3) ClearList(&L )
       //清空线性表中的内容4) ListEmpty(L)
       //判断线性表是否为空5) ListLength(L)
        //返回线性表的长度6) GetElem(L,i,& e)
        //返回线性表i位置上的元素值,通过e返回     7) PriorElem(L,cur_e,&pre_e)
       //若cur_e是线性表中的元素,且不是第一个,则返回该元素前一个元素的值8) NextElem(L,cur_e,&next_e)
       //如果cur_e是线性表中的元素,而且不是最后一个,返回它下一个元素的值9Listinsert(&L,i,e)
        //如果线性表存在了,而且i符合条件,则在i位置插入一个元素10)ListDelete(&L,i)
       //删除i位置上的元素11ListDelete_data(&L,e,order)
      //删除指定的元素e,order决定是删除一个,还是全部。12Connect_two_List(L_a,L_b,& L_c)
      //连接两个线性表,除去重复的内容    13print(L)
       //打印线性表    

三、线性表的合并与排序问题分析:

1、算法简介:

本文算法采用的是冒泡排序法,它的基本思想是比较相邻的两个数,如果前者比后者大,则进行交换。每一轮排序结束,选出一个未排序中最大的数放到数组后面,冒泡排序法是属于交换排序的,交换排序的基本思想都为通过比较两个数的大小,当满足某些条件时对它进行交换从而达到排序的目的

2、时间复杂度:

在这里插入图片描述

3、算法稳定性:

冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

四、附上合并排序的C语言源代码:

(附带保姆级注释,供初学者参考)

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

struct node{          //定义顺序表
	int *elem;
	int len;
};

void Init_arr(int len,struct node &arr)   //1、初始化顺序表
{
   int i=0,j=0,k=0;                        //2、定义i,j,k值均为0
   int t;
   arr.elem=(int *)malloc(len*sizeof(int));
   //3、为该arr顺序表分配内存空间
   if(arr.elem!=NULL)                     
    //4、内存分配是否成功的判断
   {
	   for(i=0;i<len;i++)                 
	    //5、进入for循环,当i不大于顺序表长度时,进行+1操作
         scanf_s("%d",&arr.elem[i]);         
         //6、这里手动输入顺序表的元素(可无序)
       arr.len=len;

      //冒泡排序
      for(j=0;j<len-1;j++)                
      //1、外层for循环表示arr中有len个数,比较次数为len-1
	  {
		for(k=0;k<len-j-1;k++)           
		 //2、内层for循环表示若第二个数比第一个数小进行两两交换的次数
		{
     	    if(arr.elem[k]>arr.elem[k+1]) 
     	    //3、if判断前一个数大小是否大于后一个
			{
				t=arr.elem[k];            
				//4、若是,进行交换操作,其中t为交换的中间量
     	        arr.elem[k]=arr.elem[k+1];
              	arr.elem[k+1]=t;          
              	//5、完成位置交换
		 }
	 }
 }
}
   else{printf("内存分配失败!");
      exit(0);                           
      //6、else错误操作直接退出
}
}


void Combine_arr(struct node &arr1,struct node &arr2,struct node &arr)  //归并顺序表,三个接口分别为表1,表2和合并完成的表
{
	int i=0,j=0,k=0;                          
	//1、创建第二个顺序表,步骤和第一个类似
	arr.elem=(int *)malloc(1000*sizeof(int));
	//2、为第二个顺序表申请空间
	if (arr.elem!=NULL)                       
	//3、若顺序表不空
	{
	while(i<arr1.len&&j<arr2.len)             
	//4、i表示第一个顺序表的下标,j表示第二个顺序表的下标
    {
        if(arr1.elem[i]>arr2.elem[j]){        
        //5、两两比较,若表1的i大于表2的j
            arr.elem[k++]=arr2.elem[j];       
            //6、合并后的总表的第一个数就是第二个表中的j
            j++;                             
            //7、j执行加1操作继续与第一个表中的i进行比较
	}
	else{
		arr.elem[k++]=arr1.elem[i];           
		//8、如果i为较小的那个,则合并后总表的第一个数为i
		i++;                                  
		//9、执行i加1操作,继续与第二个表中的j进行比较
	}
	}
	      if(i>=arr1.len)                    
	       //10、只剩一个表还未归并入新表(即通过i++,数组下标已经达到了第一个表的最后一个,即第一个表最大元素小于第二个表的最小元素,此时第一个表全体入新表)
	        	for(j;j<arr2.len;j++)         
	        	//11、此时只剩第二张表,进for循环
		  {
	            arr.elem[k++]=arr2.elem[j];   
	            //12、下标为j的二表元素依次进入新表
		  }
        	else
			{
		        for(i;i<arr1.len;i++)         
		        //13、如果二表最大元素小于一表最小元素,即二表全部进入新表,一表没有元素进新表
	    	    arr.elem[k++]=arr1.elem[i];   
	    	    //14、下标为i的一表元素进入新表
			}
	arr.len=k;                                
	           //15、新顺序表长度为最终的k
	}
	else
	{
		printf("内存分配失败!");
	exit(0);
	}
}

void traverse_arr(struct node &arr) 
//1、遍历显示出顺序表
{
	int i=0;
	for(i=0;i<arr.len;i++)          
	//2、不超出范围的前提下,分别通过下标打印出新表元素
    	printf("%d ",arr.elem[i]);
	printf("\n");
}



int main(void)
{
	int p,q;
	struct node arr1,arr2,arr;
	printf("顺序表1的元素个数为:");scanf_s("%d",&p);

	printf("请输入第1个顺序表元素:");Init_arr(p,arr1);
	traverse_arr(arr1);

	printf("顺序表2的元素个数为:");scanf_s("%d",&q);

	printf("请输入第2个顺序表元素:");Init_arr(q,arr2);
	traverse_arr(arr2);

	Combine_arr(arr1,arr2,arr);
	//对表一表二进行归并
	traverse_arr(arr);
	//再次遍历并输出总表
	return 0;
}

  • 10
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值