题目描述:设顺序表va中的数据元素递增有序。试写一算法,将x插入到顺序表的适当位置上,以保持该表的有序性。(习题来源于数据结构C语言版,严蔚敏,清华大学出版社,最后附该习题标答)
关键词:顺序表、递增有序(可以联想到步长的数学定义)
下面附代码,以int数据为例,方法不唯一,总体思路都基本一致,先初始化并创建该顺序表,此算法本质就是插入算法,将x从最后(最大的开始)进行开始比较,当最先发现x大于某一个数时,此时x则停止比较,插入到该数的后面,将后面的数全部往后移一位,同时数组长度也将增加1。
通过此算法,联想到插入排序,该算法本质就是插入排序所以在平均和最坏情况下的时间复杂度都是 O(n^2),最好情况下都是 O(n),空间复杂度是 O(1),后附此算法。
而本题是事先经过排序的,故属于最好的情况,所以该题的时间复杂度为O(n)。
/*Author:Lee
VScode
*/
#include <iostream>
#define MAX 10000
using namespace std;
typedef struct{
int elem[MAX];
int length;
}Sqlist;
void initlist(Sqlist *va);
Sqlist Creatlist(Sqlist *va,int num);
void Insertlist(Sqlist *va,int x);
void showlist(Sqlist *va);
int main(){
int num,x;
Sqlist a;
cout<<"Input number of list:"<<endl;
cin>>num;
initlist(&a);
Creatlist(&a,num);
showlist(&a);
cout<<"\nInput x:"<<endl;
cin>>x;
Insertlist(&a,x);
showlist(&a);
return 0;
}
void initlist(Sqlist *va){
va->length=0;
}
Sqlist Creatlist(Sqlist *va,int num){
int init,step,i;
cout<<"Input initial value and step:"<<endl;
cin>>init>>step;
for(i=0;i<num;i++){
va->elem[i]=init+i*step;
}
va->length=num;
return *va;
}
void Insertlist(Sqlist *va,int x){
int i;
for(i=va->length;i>0,x<va->elem[i-1];i--){
va->elem[i]=va->elem[i-1];
}
va->elem[i]=x;
va->length++;
}
void showlist(Sqlist *va){
int i;
cout<<"List show:"<<endl;
for(i=0;i<va->length;i++){
cout<<(va->elem[i])<<" ";
}
}
习题标答(较简略)
Status InsertOrderList(SqList &va,ElemType x)
{
//在非递减的顺序表va 中插入元素x 并使其仍成为顺序表的算法
int i;
if(va.length==va.listsize)return(OVERFLOW);//避免溢出
for(i=va.length;i>0,x<va.elem[i-1];i--)
va.elem[i]=va.elem[i-1];
va.elem[i]=x;
va.length++;
return OK;
}
插入排序
1.认为第一个元素是排好序的,从第二个开始遍历。
2.拿出当前元素的值,从排好序的序列中从后往前找。
3.如果序列中的元素比当前元素大,就把它后移。直到找到一个小的。
4.把当前元素放在这个小的后面(后面的比当前大,它已经被后移了)
void insert_sort(int a[],int len){
for(int i=1;i<len;i++){
int temp=a[i];
int j=i-1;
while(j>=0&&temp<a[j]){
a[j+1]=a[j];
j--;
}
a[j+1]=temp;
}
}