1.
顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删除的元素,空出位置由最后一个元素填补,若顺序表为空,则显示出错信息并退出运行。
算法大致思想是扫描整个顺序表寻找最小值,辅助变量k为记录最小值位置方便最后填补。出错点在最后需要删除最后一个元素(L.length–)属实语文理解水平不行了。。。
bool DeleteElem(SqList &L,int &e){
if(L.length==0){
printf(“出错了!”);
return false;
}
int k=0,i;
e=L.data[0];
for(i=1;i<L.length;i++){
if(L.data[i]<min)
e=L.data[i];
k=i; //记录是哪个位置的元素最小
}
L.data[k]=L.data[length-1];
L.length--; //记得删除
return true;
}
2.
顺序表中的元素逆置,要求空间复杂度为O(1)
大概思想是把顺序表劈成两半,然后交换对应位置的元素。长度是偶数奇数都可以用length/2来实现。
void ListReverse(SqList &L)
int i,k;
for(i=0;i<L.length/2;i++){ //判断条件不能➕等号,当length是奇数时候中间元素可以自己交换,但是偶数时就多交换了一次
k=L.data[i];
L.data[i]=L.data[L.length-i-1];
L.data[L.length-i-1]=k;
}
}
3.
长度为n的顺序表L,要求删除所有值为x的数据元素。时间复杂度O(n),空间复杂度O(1)
方法1:
时间复杂度要求O(n),不能套双循环前移元素。空间复杂度要求O(1)不能新开辟数组。
所以最优的方法是在原数组上改造,把每一个不等于x的元素重新组成这个数组。
void DeleteElemX(Sqlist &L,ElemType x){
int i,k=0;
for(i=0;i<n;i++){
if(L.data[i]!=x){ //注意找出不等于x的那些数组元素(而不是等于x)
L.data[k]=L.data[i];
k++;
}
}
L.length=k;
}
方法2:
用k记录等于x的元素个数,然后将不等于x的元素前移k位置。
void DeleteElemX(Sqlist &L,ElemType x){
int i,k=0;
for(i=0;i<n;i++){
if(L.data[i]==x)
k++;
else
L.data[i-k]=L.data[i];
i++;
}
L.length=L.length-k;
}
emmm虽然能看懂但是想不出来。。
4.
从有序表中删除其值在s与t之间的所有元素,要求s<t。若线性表为空或者st值不合理退出运行。
注意是有序表,元素是有顺序的!
bool Delete_st(Sqlist &L,ElemType s,ElemType t){
if(L.length==0||s>=t)
return false;
int i,j,k=0,n=0;
for(i=0;i<L.length;i++){
if(L.data[i]==s){ //先找到等于s的元素的数组下标放到i中(记录位置)
k=1;
break;
}
}
if(k=0)
return false; //没有介于s到t之间的元素,直接返回。
for(j=i;j<L.length;j++){ //找到大于t的第一个元素
if(L.data[j]>t)
break;
}
for(;j<L.length;i++,j++) //前移,干掉前面的元素
L.data[i]=L.data[j];
L.length=i;
return true;
}
感觉这道题比较抽象需要画图。
5.
从顺序表中删除其值在s与t之间的所有元素,要求s<t。若线性表为空或者st值不合理退出运行。
顺序表中删除,注意和上题区别。
bool Delete_st(Sqlist &L,ElemType s,ElemType t){
if(L.length==0||s>=t)
return false;
int i,j,k=0;
for(i=0;i<L.length;i++){
if(L.data[i]>=s&&L.data[i]<=t){
k++;
}
else
L.data[i-k]=L.data[i]; //关键算法
}
L.length=L.length-k;
return true;
}
这个方法也适用于上题。
6.
删除有序顺序表中值重复的元素。
bool DeleteElem(SqList &L){
if(L.length==0)
return false;
int i,j,temp,k=0;
temp=L.data[0];
for(i=1;i<L.length;i++){
if(L.data[i]==temp)
k++;
else{
temp=L.data[i];
L.data[i-k]=L.data[i];
}
}
L.length=L.length-k;
return true;
}
验证一下:
#include <stdio.h>
typedef struct {
int data[8]; //顺序表元素
int length; //顺序表当前长度
}SqList; //类型定义
void CreateList(SqList &L)
{
int i;
for (i = 0; i < L.length; i++)
{//通过循环将数组元素全部遍历放入顺序表中
scanf_s("%d", &L.data[i]); //输入方式
}
}
bool DeleteElem(SqList &L) {
if (L.length == 0)
return false;
int i, temp, k = 0;
temp = L.data[0];
for (i = 1; i < L.length; i++) {
if (L.data[i] == temp)
k++;
else {
temp = L.data[i];
L.data[i - k] = L.data[i];
}
}
L.length = L.length - k;
return true;
}
int main()
{
int i, j;
SqList L;
L.length = 8;
CreateList(L);
DeleteElem(L);
for (j = 0; j < L.length; j++)
printf("%d ", L.data[j]);
return 0;
}
7.*
两个有序顺序表合为一个新的有序表。(算法典型,需要掌握!!)
i和j分别看成两个游标,当被选中放入p表后,游标向后移动直到遍历完顺序表为止。(这样可以做到每一个元素都经过了比较,如果只有一个游标则会丢失元素)
需要注意两个表的长度不一样,短的先遍历完,长的需要继续放入p表中。
SqList MergeList(SqList& L, SqList& M) {
int i,j,k;
SqList p;
p.length = L.length + M.length;
for (i = 0,j = 0,k = 0; i < L.length &&j < M.length;k++) { //注意逻辑关系是“与”
if (L.data[i] < M.data[j]) {
p.data[k] = L.data[i];
i++;
}
else {
p.data[k] = M.data[j];
j++;
}
}
if (i < L.length)
for (; i < L.length; i++) {
p.data[k] = L.data[i];
k++;
}
else
for (; j < M.length; j++) {
p.data[k] = M.data[j];
k++;
}
return p;
}
验证:
8.
一维数组A[M+N]中包含两个线性表,函数功能为将两个线性表位置交换。
为了验证方便,全部统一为顺序表了。
运用反转函数,反转三次顺序表。第一次反转全部,然后分别反转两个子顺序表。
注意反转函数传入的变量:假如第一个表长度为3,第二个长度为4.经过一次反转函数后从3+4变为4+3.
void ReverseList(SqList &L, int m, int n) {
int i,j=0,temp;
for (i = m-1; j < (n-m+1)/2; i++,j++) {
temp = L.data[i];
L.data[i] = L.data[n + m - i-2];
L.data[n + m - i - 2] = temp;
}
}
ReverseList(L,1,M+N);
ReverseList(L, 1, M);
ReverseList(L, M+1, M+N);
9.
已知线性表中的元素有序递增,要求函数完成在表中查找数值为x的元素。若找到,则将其与后续元素位置交换,若找不到,则将其插入表中并使表中元素仍递增有序。
void Find_X(SqList& L, int x) {
int i,j,k=0;
for (i = 0; i < L.length; i++) {
if (L.data[i] == x)
{
L.data[i] = L.data[i + 1];
L.data[i + 1] = x ;
break;
}
if (L.data[i] < x && L.data[i+1] > x)
{
k = 1;
break;
}
}
if (k == 1) {
L.length = L.length + 1;
for (j = L.length-1; j > i+1; j--) {
L.data[j] = L.data[j-1]; //向后移动
}
L.data[i + 1] = x;
}
}
验证:
取X=6