实验一 倒置
/**********************************/
/*文件名称: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