提起数据结构这门学科,相信绝大多数学计算机的同学对此门课程并不陌生,很多人对程序的定义是:程序 = 构数据结 + 算法,可见数据结构的重要性,想要写出好的程序,数据结构是一门必须要掌握的学科。
然而,很多人却把数据结构这门课学成了“离散数学”,只是初步的掌握了其中的手动模拟过程,真正要上手写代码的时候,往往感觉无从下手,这不是个例,而是一种通病。
数据结构在考研中同样占据着举足轻重的地位,无论是国家统一命题的计算机专业基础综合(408),还是各大高校的自命题中都会经常浮现出数据结构的身影。
因此,可见数据结构的重要性。考研中,大多数的学校让写的是伪码,这也就意味着你不需要写完整的程序,只需要把相应的接口留出来就行了。但是大家最好还是把代码实际敲出来运行一下,才会发现自己程序的bug,不断地踩坑,才能更好的避坑。接下来我们来看一道例题,来自王道书的第一个代码题。
题目1:从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。空出的位置由最后一个元素填补,若表空则显示出错信息并退出程序。
程序如下:
#include
#define MaxSize 10
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
void InitSqList(SqList &l);//初始化线性表的函数声明明,因为线性表的数据长度会变化,所以形参设置成引用型
int DelMin(SqList &l);//删除最小值的函数声明
void Output(SqList l);//输出线性表的函数声明
int main()
{
SqList l;
InitSqList(l);
printf("初始化的线性表:");
Output(l);
printf("\n被删元素:");
int del_num = DelMin(l);
printf("%d\n",del_num);
printf("输出结果:");
Output(l);
return 0;
}
void InitSqList(SqList &l)//这个函数对线性表进行初始化,我用的是直接对每个元素进行赋值,只是为了测试,当然可以用scanf用来输入
{
l.data[0] = 3;
l.data[1] = 2;
l.data[2] = 5;
l.data[3] = 8;
l.data[4] = 4;
l.length = 5;
}
int DelMin(SqList &l)
{
int min = l.data[0];//默认第零个元素最小
int minindex = 0;//用来记录最小值下表
if(l.length == 0)
{
printf("null sqlist");
}
for(int i = 0;i
运行结果如下:
当然在考研中,如果这样答题固然是对的,但是代码太冗余,数据结构在考研中考察的是思想,因此我们只需要给出相应的接口就行了,如果觉得不放心,可以把结构体写出来,此题的参考答案如下:
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
int DelMin(SqList &l)
{
int min = l.data[0];//默认第零个元素最小
int minindex = 0;//用来记录最小值下表
if(l.length == 0)
{
printf("null sqlist");
}
for(int i = 0;i
题目2:设计一个高效的算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)。
程序如下:
#include
#define MaxSize 10
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
void InitSqList(SqList &l);//初始化线性表的函数声明明,因为线性表的数据长度会变化,所以形参设置成引用型
void ReserveSqList(SqList &l);//逆置元素的函数声明
void Output(SqList l);//输出线性表的函数声明
int main()
{
SqList l;
InitSqList(l);
printf("初始化的线性表:");
Output(l);
ReserveSqList(l);
printf("\n输出逆置结果:");
Output(l);
return 0;
}
void InitSqList(SqList &l)//这个函数对线性表进行初始化,我用的是直接对每个元素进行赋值,只是为了测试,当然可以用scanf用来输入
{
l.data[0] = 3;
l.data[1] = 2;
l.data[2] = 5;
l.data[3] = 8;
l.data[4] = 4;
l.length = 5;
}
void ReserveSqList(SqList &l)//题目指出空间复杂度为O(1),因此不能开辟新的内存空间,只能在数组内部进行操作
{
int temp;//用于交换的中间变量
for(int i = 0;i
运行结果如下:
此题的参考答案如下:
#define MaxSize 10
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
void ReserveSqList(SqList &l)//题目指出空间复杂度为O(1),因此不能开辟新的内存空间,只能在数组内部进行操作
{
int temp;//用于交换的中间变量
for(int i = 0;i
题目3:对长度为n的顺序表L,编写一个时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的元素。
程序如下:
#include
#define MaxSize 10
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
void InitSqList(SqList &l);//初始化线性表的函数声明明,因为线性表的数据长度会变化,所以形参设置成引用型
int DelAllx1(SqList &l,int x,int n);//删除最小值的函数声明
int DelAllx2(SqList &l,int x,int n);
void Output(SqList l);//输出线性表的函数声明
int main()
{
SqList l;
InitSqList(l);
printf("初始化的线性表:");
Output(l);
DelAllx2(l,2,5);
printf("\n输出结果:");
Output(l);
return 0;
}
void InitSqList(SqList &l)//这个函数对线性表进行初始化,我用的是直接对每个元素进行赋值,只是为了测试,当然可以用scanf用来输入
{
l.data[0] = 3;
l.data[1] = 2;
l.data[2] = 2;
l.data[3] = 8;
l.data[4] = 4;
l.length = 5;
}
int DelAllx1(SqList &l,int x,int n)
{
/*用这种算法的时候,很明显时间复杂度是O(x^2)
不过在408统考中,只要能够实现功能,即使采用暴力求解的算法,
也能拿到大部分分数,所以这种算法适合大部分人采用
*/
int count = 0;//coun用来记录x的个数
for(int i = 0;i
运行结果如下:
此题的参考答案如下:
#define MaxSize 10
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
int DelAllx1(SqList &l,int x,int n)
{
/*用这种算法的时候,很明显时间复杂度是O(x^2)
不过在408统考中,只要能够实现功能,即使采用暴力求解的算法,
也能拿到大部分分数,所以这种算法适合大部分人采用
*/
int count = 0;//coun用来记录x的个数
for(int i = 0;i
题目4:设从有序顺序表中删除其值在给定值s和t之间(包含s和t,要求是s 程序如下: 运行结果如下: 此题的参考答案如下: 题目5:从有序的顺序表中删除所有其值重复的元素,使得表中所有元素不重复。 程序如下: 运行结果如下: 此题的参考答案如下 : 题目6:将两个有序顺序表合并成一个新的有序顺序表,并由函数返回结果顺序表。 程序如下: 运行结果如下: 此题的参考答案如下 : 题目7:从已知在一维数组A[m+n]中依此存放两个线性表(a1,a2,a3……am)和(b1,b2,b3……bn)试编写一个函数,将数组中两个顺序表的位置交换,即将(b1,b2,b3……bn)放在(a1,a2,a3……am)的前面。 程序如下: 运行结果如下: 此题的参考答案如下 : 题目8:从线性表(a1,a2,a3……an)中的元素递增有序且按顺序存储于计算机内。要求设计一个算法,完成用最少时间在表中查找值为x的元素,若找到则将其与后继元素位置相交换,若找不到则将其插入到表中并使表中元素扔递增有序。 程序如下: 运行结果如下: 此题的参考答案如下 : 题目9:【2010统考真题】设将n(n>1)个整数存放到一维数组R中。设计一个在时间和空间两方面都尽可能高效的算法。将R中保存的序列循环左移P(0
1)给出算法的基本设计思想。 答:这一题跟前面的第七题几乎是一样的,可以先将0-p-1的元素进行逆置,然后将p-1-n-1元素进行逆置,然后将整个数组进行逆置。 2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。 (这里虽然说可以用java语言,但是后面的真题已经把java给删除了,只让用c和c++) 3)说明你所设计的算法的时间和空间复杂度。 时间复杂度O(n),空间复杂度O(1) 运行结果如下: 题目10:【2011统考真题】从一个长度为L(L>=1)的升序序列S,处在第个位置的数称为S的中位数。例如,若序列S1=(11,13,15,17,19)则S1的中位数是15,两个序列的中位数是含他们所有元素的升序序列的中位数。例如,若S2=(2,4,6,8,20),则S1和S2的中位数是11。现在有两个升序序列A和B,试设计一个在时间和空间上都尽可能高效的算法,找出A和B的中位数。要求: 1)给出算法的基本设计思想。 答:这一题跟前面的第六题也是基本一样的,首先找到s1和s2长度的最小值,遍历到长度最小值为止,当s1的data【i】比较小的时候则插入到新的数组中,直到其中一个序列插入结束,然后另一个序列剩下的全部插入到新的数组中。 2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。 3)说明你所设计的算法的时间和空间复杂度。 时间复杂度O(min(n,m)),空间复杂度O(m+n) 程序如下: 运行结果如下: 题目11:【2013统考真题】从已知一个整数序列A=(a0,a1,……,an-1)其中0<=ai 1)给出算法的基本设计思想。 用两个for循环,外层循环用来遍历数组的每个下标,内层元素用来遍历下标后到结束的元素值,得到每个下标元素的长度,并更新每次的遍历结果,得到候选主元素的lengthmax、和value。 2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释。 3)说明你所设计的算法的时间和空间复杂度。 时间复杂度O(),空间复杂度O(1). 程序如下: 运行结果如下: 题目12:【2018统考真题】从给定一个含n(n>=1)个整数的数组,请设计一个在时间和空间上尽可能高效的算法,找出数组中未出现的最小正整数。例如,数组{-5,3,2,3}中未出现的最小正整数是1;数组{1,2,3}中未出现的最小正整数是4。要求: 1)给出算法的基本设计思想。 遍历数组,找到负数直接退出循环,用第一个元素当做最大值,当有大于max的时候,更新max;如果有负数,返回1,没有负数返回max+1. 2)根据设计思想,采用C或C++语言描述算法,关键之处给出注释。 3)说明你所设计的算法的时间和空间复杂度。 时间复杂度O(n),空间复杂度O(1) 程序如下: 运行结果如下: 写道这里,王道书上的线性表的顺序存储部分的代码应该是完成了,代码题其实重要的是思路,有思路才能动手写,还是得多练习,多思考,多模仿,形成自己的代码,在套路中学习。才能得到成长。下一个专题,我会更新线性表的链式存储部分的代码。 (如有错误,恳请各位不吝赐教,有时间我会一直更新数据结构的代码)#include
#define MaxSize 10
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
int DelElem1(SqList &l,int s,int t)
{
/*可以遍历整个数组,对s和t之间的元素进行删除,并依此移动后面的元素*/
if(l.length == 0)
{
printf("null sqlist");
return 0;
}
if(s >= t)
{
printf("error range");
return 0;
}
int count = 0;//count用来记录s和t之间的元素
for(int i = 0;i
#include
#define MaxSize 10
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
int DelSam(SqList &l)
{
int count = 0;//count用来记录不是重复元素的下标
for(int i = 0;i
#include
#define MaxSize 16//注意数组的长度,超出长度会输出错误的结果
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
SqList MergeSqList(SqList &l1,SqList &l2,SqList &l)
{
int length = l1.length < l2.length ? l1.length:l2.length;//得到两个顺序表的最小长度
int i = 0,j = 0;
int count = 0;
while(i
#include
#define MaxSize 10
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
void ReserveSqList(SqList &l,int m,int n)
{
int temp;//用于交换的中间变量
for(int i = 0;i
#include
#define MaxSize 16
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
void InsertElem(SqList &l,int x)
{
int flag = 1;//1表示 找到了,0表示没找到
int temp;
int i;
for(i = 0;i
#define MaxSize 10
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
void ReserveSqList(SqList &l,int m)
{
int temp;//用于交换的中间变量
int n = l.length-m;
for(int i = 0;i
#define MaxSize 16//注意数组的长度,超出长度会输出错误的结果
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
void MergeSqList(SqList &l1,SqList &l2,SqList &l)
{
int length = l1.length < l2.length ? l1.length:l2.length;//得到两个顺序表的最小长度
int i = 0,j = 0;
int count = 0;
while(i
#include
#define MaxSize 16
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
void FindNumberMax(SqList &l)
{
int lengthmax = 0,length=0,value=0;//lengthmax 用来记录最大的元素长度,length用来保存每次查找到的元素长度,value用来保存候选主元素值
for(int i = 0;i
#include
#define MaxSize 10
typedef struct //定义一个结构体变量
{
int data[MaxSize]; //定义结构体变量的属性,data数组用来存放数据
int length; //length用来记录data数组的长度
}SqList;//给结构体取一个别名
int FindMinZheng(SqList &l)
{
int flag = 0;//0表示没有负数,1表示有负数
int max = l.data[0];
for(int i = 0;i
#include