[数据结构]练习1-线性表的顺序实现

实验一 倒置

/**********************************/
/*文件名称:lab1-01.c             */
/**********************************/
/*基于sequlist.h中定义的顺序表,编写算法函数reverse(sequence_list *L),实现顺序表的就地倒置。*/
#include "sequlist.h"

void reverse(sequence_list *L)//这里为什么是*L 
{
	//记得判断是否为空
	if(L->size==0)
	{
		printf("这里是空的");
		return; 
	} 
	datatype temp; //为什么是datatype,不是int 
	int left=0;
	int right=L->size-1;//注意不是a[size-1]为什么呢 ,看下面 
	while(left<right)//这里刨除了奇数左右相等,偶数右边小于左边 
	{
		temp=L->a[left];
		L->a[left]=L->a[right];
		left++;
		L->a[right]=temp;
		right--;
	}
	return;
}
int main()
{
    sequence_list L;			/*定义顺序表*/
    input(&L);	        		/*输入测试用例*/
    print(&L);                  /*输出原表*/
    reverse(&L);		            /*顺序表倒置*/
    print(&L);                  /*输出新表*/
}

在这里插入图片描述

总结

先判断顺序表是否为空,再两个指针指向左右两边,遍历的同时实现倒置

实验二 奇偶分开

/**********************************/
/*文件名称:lab1_02.c             */
/**********************************/

/*编写一个算法函数void sprit( sequence_list *L1,sequence_list *L2,sequence_list *L3),
将顺序表L1中的数据进行分类,奇数存放到存到顺序表L2中,偶数存到顺序表L3中,编写main()进行测试。
*/

#include "sequlist.h"
/*请将本函数补充完整,并进行测试*/
void sprit(sequence_list *L1,sequence_list *L2,sequence_list *L3)
{
	if(L1->size==0){
		printf("是空的");
		return;
	}
	int left,i=0,j=0;
	for(left=0;left<L1->size;left++){
            //记得用循环遍历顺序表
	if(L1->a[left]%2) {//奇数存放到存到顺序表L2中,偶数存到顺序表L3中
		L2->a[i]=L1->a[left];
//		L2->size++;//增加内存
		i++;
	}
	else{
		L3->a[j]=L1->a[left];
//		L3->size++;
		j++;
	}
	L2->size=i;
	L3->size=j;
	}
	return;
}
int main()
{   sequence_list L1,L2,L3;		/*定义三个顺序表*/
    input(&L1);				    /*输入L1*/
    sprit(&L1,&L2,&L3);		    /*对L1进行分类*/
    print(&L1);				    /*输出L1、L2和L3*/
    print(&L2);
    print(&L3);
}

在这里插入图片描述

总结

先判断顺序表表是否为空,在遍历中分别把指针放在顺序表表两边,最后告诉顺序表表的size

实验三 合并

/*已知顺序表L1,L2中数据由小到大有序,请用尽可能快的方法将L1与L2中的数据合并到L3中,使数据在L3中按升序排列。*/

#include "sequlist.h"
/*请将本函数补充完整,并进行测试*/
void merge(sequence_list *L1,sequence_list *L2,sequence_list *L3)
{
	int i=0,j=0;
	if(L1->size==0||L2->size==0)
	{
		printf("是空的!");
		return;
	}
	else if(L1->size+L2->size>MAXSIZE) //考虑栈溢出 
	{
		printf("已经满啦!");
		return; 
	}
//	if(L1->size<L2->size)
//	{
//	
//		if(L1->a[i]<L2->a[j]){
//			L3->a[m++]=L1->a[i];
//			i++;
//			if(i==L1->size){
//				for(n=L1->size;n<L2->size-1;n++)
//				{
//					 L3->a[m++]= L2->a[n];
//					 if(L2->a[n]==0){
//					 	return;
//					 } 
//			}
//		}else{
//				L3->a[m++]=L2->a[i];
//				j++;
//		}
//		
//	} 
//	}
else{
	initseqlist(L3);//为什么要初始化? 
	while(i<L1->size&&j<L2->size)
	{
		if(L1->a[i]<L2->a[j])
		{
			L3->a[L3->size++]=L1->a[i++];//改成size++,不是 L3->a[m++]
		}else{
			L3->a[L3->size++]=L2->a[j++];//不是L3->a[size++]
		}
	}
	for(;i<L1->size;i++){
		L3->a[L3->size++]=L1->a[i];
	}
	for(;j<L2->size;j++){
		L3->a[L3->size++]=L2->a[j];
	}
}
	return;

}
int main()
{
    sequence_list L1,L2,L3;
    input(&L1);				/*输入时请输入有序数据*/
    input(&L2);				/*输入时请输入有序数据*/
    merge(&L1,&L2,&L3);		/*合并数据到L3*/
    print(&L3);				/*输出L3*/
}

在这里插入图片描述

总结

因为是合并计算,所以要判断顺序表表是否已空或是否已满,然后将比较两个顺序表表,将最小的放进新顺序表表里,当一个顺序表表为空后,开始遍历另一个顺序表表剩余的元素并全放进这个顺序表表中,最后告诉顺序表表的size

实验四 交集

/*假设顺序表la与lb分别存放两个整数集合,函数inter(seqlist *la,seqlist *lb,seqlist *lc)
的功能是实现求顺序表la与lb的交集存放到顺序表lc中,请将函数补充完整.  */

/**********************************/
/*文件名称:lab1_04.c                 */
/**********************************/
#include "sequlist.h"
/*请将本函数补充完整,并进行测试*/
void  inter(sequence_list *la,sequence_list *lb,sequence_list *lc)
{
	int i=0,j=0;
	if(la->size==0||lb->size==0)
		{
			printf("是空的!");
			return;
		}
	else{
			initseqlist(lc);
			for(i=0;i<la->size;i++){
			for(j=0;j<lb->size;j++){
				if(la->a[i]==lb->a[j]){
					lc->a[lc->size++]=la->a[i];//a[lc->size++]忘写a 了 
				}
			}
			}
		}
}
int main()
{
  sequence_list la,lb,lc;
  inputfromfile(&la,"1.txt"); 		/*从文件1.txt建立顺序表*/
  inputfromfile(&lb,"2.txt");		/*从文件2.txt建立顺序表*/
  print(&la); 				 	    /*输出la*/
  print(&lb);  				        /*输出lb*/
  inter(&la,&lb,&lc);   		    /*求la与lb的交集存于lc中*/
  print(&lc); 					    /*输出lc*/
  return 0;
}

在这里插入图片描述

总结

先判断顺序表表是否为空,然后双顺序表表循环,如果出现同一个元素放进新链表,然后跳出循环

实验五 本顺序表中奇偶分开

/*
请编写一个算法函数partion(sequence_list *L),尽可能快地将顺序表L中的所有奇数调整到表的左边,
所有偶数调整到表的右边,并分析算法的时间复杂度。
*/
/**********************************/
/*文件名称:lab1_05.c                 */
/**********************************/
#include "sequlist.h"
/*请将本函数补充完整,并进行测试*/
void partion(sequence_list *L)
{
	datatype temp;
	int i=0,j=L->size-1;
	while(i<j){
	while(i<L->size&&L->a[i]%2==1){//从右向左扫描偶,反之扫描奇数,交换 
		i++;
	} 
	while(j>=0&&L->a[j]%2==0){//从右向左扫描偶,反之扫描奇数,交换 
			j--;
		} 
		if(i<j){
			temp=L->a[i];
			L->a[i]=L->a[j];
			L->a[j]=temp;
			i++;
			j--;//i就增加一位,j就减少一位 
		}
	}
	return;
}
int main()
{
  sequence_list L;
  inputfromfile(&L,"3.txt");
  print(&L);  						/*输出表L*/
  partion(&L);
  print(&L);  						/*输出新表*/
  return 0;
}

在这里插入图片描述

总结

在遍历中分别把指针放在顺序表表两边,同时遍历,如果奇偶位置错误,直接进行调换

实验六 删除

/*
已知长度为n的线性表L采用顺序存储结构,编写一个复杂度为O(n)、
空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素。
*/
/**********************************/
/*文件名称:lab1_06.c                 */
/**********************************/
#include "sequlist.h"
/*请将本函数补充完整,并进行测试*/
/*解法一:用k记录顺序表L中不等于x的元素个数(即需要保存的元素个数),
  边扫描L边统计k,并将不等于x的元素向前放在k位置上,最后修改L的长度。
  */
void delNode1(sequence_list *L,datatype x)
{
	if(L->size==0)
		{
			printf("这里是空的");
			return; 
		} 
   int k=0,i=0;
   for(i=0;i<L->size;i++){
   	if(L->a[i]==x) {//等于x的元素个数,不是a[x] 
	   	k++;
//	   	
//	 	for(j=L->a[t];j<L->size;j++){
//		   	  	t=i+1;
//L->a[j-1]=L->a[j];忘记判断未相同情况了 
		   }
	else {
//				for(j=L->a[i];j<L->size;j++){
//					   	L->a[j-1]=L->a[j];
	
	
		L->a[i-k]=L->a[i];//忘记判断未相同情况了
	}
	   }
    L->size=L->size-k;//这里不要加0 
	return;
}
/*
    解法二:用k记录顺序表L中等于x的元素个数,边扫描L边统计K,并将不等
    于x的元素前移k个位置,最后修改L的长度。
*/

int main()
{
  sequence_list L;
  int x;
  input(&L);
  print(&L);  	/*输出表L*/
  printf("请输入要删除的数:");
  scanf("%d",&x);
  delNode1(&L,x);
  //delNode2(&L,x);
  printf("删除%d后的顺序表为:\n",x);
  print(&L);  						/*输出新表*/
  return 0;
}

在这里插入图片描述

总结

用k记录顺序表L中不等于x的元素个数(即需要保存的元素个数),边扫描L边统计k,并将不等于x的元素向前放在k位置上,最后修改L的长度。

实验七 考研题练习

/*
设将n(n>1)个整数存放到一维数组R中。试设计一个时间和空间两方面尽
可能高效的算法,将R中整数序列循环左移p(0<p<n)个位置,即将R中的
数据序列(X0,X1,…,Xn-1)变换为(Xp,Xp+1,…,Xn-1,X0,X1,…,Xp-1),
要求:
(1)给出算法的基本设计思想。
(2)根据设计思想,采用C、C++或JAVA语言描述算法,关键之处给出注释。
(3)说明你所设计算法的时间复杂度和空间复杂度。

*/
/**********************************/
/*文件名称:lab1_06.c                 */
/**********************************/
#include "sequlist.h"
//函数reverse()的功能是将顺序表L->a[left..right]进行首尾倒置,请将函数补充完整
void reverse(sequence_list *L,int left,int right)
{
		if(L->size==0)
		{
			printf("这里是空的");
			return; 
		} 
		datatype temp;
	
		while(left<right)
		{
			temp=L->a[left];
			L->a[left++]=L->a[right];
			L->a[right--]=temp;
		}
		return;
   
}
/*
    解法1:函数leftShift1()的功能是实现顺序表循环左移p位,其中n为顺序表中的元素个数
*/
void leftShift1(sequence_list *L,int n,int p)
{
    if (p>0 && p<n)
    {
          		//将顺序表L的全部数据倒置,请填上适当语句
         		//将顺序表L的前n-p个元素倒置,请填上适当语句
        		 //将顺序表L的后p个元素倒置,请填上适当语句
    datatype temp;
			
	int left=0;
	int right=L->size-p-1;//不是size-p+1 
	while(left<right)//这里刨除了奇数左右相等,偶数右边小于左边 
	{
		temp=L->a[left];
		L->a[left++]=L->a[right];
		L->a[right--]=temp;
	}
			int left2=p;
			int right2=L->size-1;
			while(left2<right2)//这里刨除了奇数左右相等,偶数右边小于左边 
			{
				temp=L->a[left2];
				L->a[left2++]=L->a[right2];
				L->a[right2--]=temp;
			}
			int left3=0;
			int right3= L->size-1;
	       	reverse( L, left3,right3);//这里没有*L,因为L传进去才是*L ,传过来不能照搬,int,requense_list都不要 
	    }
	return;
    	
}
/*
    解法2:函数leftShift2()的功能是实现顺序表循环左移p位,其中n为顺序表中的元素个数
*/

int main()
{
  sequence_list L;
  int p;
  input(&L);
  printf("线性表为:\n",p);
  print(&L);  	/*输出表L*/
  printf("请输入循环左移的位数:");
  scanf("%d",&p);
  leftShift1(&L,L.size,p);
//  leftShift2(&L,L.size,p);  //分别测试
  printf("循环左移%d位后的线性表为:\n",p);
  print(&L);  	/*输出新表*/
  return 0;
}

在这里插入图片描述

总结

将前面一段倒置,将后面一段倒置,最后首尾倒置

sequlist.h

#include  <stdio.h>
#include  <stdlib.h>
/**********************************/
/*顺序表的头文件,文件名sequlist.h*/
/**********************************/
 #define MAXSIZE 100
 typedef int datatype;
 typedef struct{
   datatype a[MAXSIZE];
   int size;
 }sequence_list;

/**********************************/
/*函数名称:initseqlist()         */
/*函数功能:初始化顺序表          */
/**********************************/
void initseqlist(sequence_list *L)
{	L->size=0;
}
/**********************************/
/*函数名称:input()               */
/*函数功能:输入顺序表            */
/**********************************/
void input(sequence_list *L)
{  datatype x;
   initseqlist(L);
   printf("请输入一组数据,以0做为结束符:\n");
   scanf("%d",&x);
   while (x)
   	{	L->a[L->size++]=x;
		     scanf("%d",&x);
	     }
}
/**********************************/
/*函数名称:inputfromfile()       */
/*函数功能:从文件输入顺序表      */
/**********************************/
void inputfromfile(sequence_list *L,char *f)
{  int i,x;
   FILE *fp=fopen(f,"r");
   L->size=0;
   if (fp)
   {   while ( ! feof(fp))
        {
            fscanf(fp,"%d",&L->a[L->size++]);
        }
        fclose(fp);
   }
}
/**********************************/
/*函数名称:print()               */
/*函数功能:输出顺序表            */
/**********************************/
void print(sequence_list *L)
{   int i;
    for (i=0;i<L->size;i++)
       {    printf("%5d",L->a[i]);
            if ((i+1)%10==0) printf("\n");
       }
    printf("\n");
}

1.txt

10
20
40
50
60
80
90
100

2.txt

10
30
50
80
90
100
120
140

3.txt

11
20
13
45
50
66
77
80
90
99
  • 17
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值