数据结构-王道-习题-顺序表(1-8)
1、从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删除的元素的值。空出的位置由最后的一个元素填补,若顺序表为空,则显示错误信息并退出运行。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct SQList {
int * pData;
int length=0;
int Maxsize=10 ;
}SqList,*pSqList;
bool DelMinElement(pSqList pL, int *val);
void Traverse(pSqList pL);
void InitSqlist(pSqList pL);
int main(void){
SqList L;
int val;
InitSqlist(&L);
Traverse(&L);
if (DelMinElement(&L, &val)) {
printf_s("最小元素:%d 已删除!\n",val);
}
Traverse(&L);
return 0;
}
void InitSqlist(pSqList pL) {
pL->pData = (int*)malloc(sizeof(int)*pL->Maxsize);
int a[5] = { 3,5,9,1,10 };
for (int i = 0; i < 5; i++) {
pL->pData[i] = a[i];
pL->length++;
}
return;
}
void Traverse(pSqList pL) {
int i;
if (pL->length == 0) {
exit(-1);
}
for (i = 0; i < pL->length; i++) {
printf_s("%d ", pL->pData[i]);
}
printf_s("\n");
}
bool DelMinElement(pSqList pL, int *val) {
if (pL->length == 0){
printf_s("顺序表为空!\n");
return false;
}
int pos=0;//标记最小元素的位置
int i;
*val = pL->pData[0];
for (i = 1; i < pL->length; i++) {
if (*val > pL->pData[i]) {
*val = pL->pData[i];
pos = i;
}
}
pL->pData[pos] = pL->pData[pL->length - 1];
pL->length--;
return true;
}
运行结果:
2、设计一个高效的算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1)。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct SQList {
int * pData;
int length = 0;
int Maxsize = 10;
}SqList, *pSqList;
void Traverse(pSqList pL);
void InitSqlist(pSqList pL);
void Inversion(pSqList pL);
int main(void) {
SqList L;
InitSqlist(&L);
Traverse(&L);
printf_s("倒置\n");
Inversion(&L);
Traverse(&L);
return 0;
}
void InitSqlist(pSqList pL) {//初始化
pL->pData = (int*)malloc(sizeof(int)*pL->Maxsize);
int a[7] = { 3,5,9,1,10,8,11 };
for (int i = 0; i < 7; i++) {
pL->pData[i] = a[i];
pL->length++;
}
return;
}
void Traverse(pSqList pL) {//遍历
int i;
if (pL->length == 0) {
exit(-1);
}
for (i = 0; i < pL->length; i++) {
printf_s("%d ", pL->pData[i]);
}
printf_s("\n");
}
void Inversion(pSqList pL) {//倒置
int i = 0;
int j = pL->length -1;
for (i, j; i < j; i++, j--) {
int t;
t = pL->pData[i];
pL->pData[i] = pL->pData[j];
pL->pData[j] = t;
}
return;
}
运行结果:
3、对长度为n的顺序表l编写一个时间复杂度为o(n),空间复杂度为o(1) 的算法,该算法删除线性表中所有值为x的数据元素。
方法一、用k记录所有等于x的数据元素个数
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct sqlist {
int * pdata;
int length = 0;
int maxsize = 15;
}sqlist, *psqlist;
void traverse(psqlist pl);//遍历
void initsqlist(psqlist pl);//初始化
void delvalofx(psqlist pl, int x);//删除
int main(void) {
sqlist l;
initsqlist(&l);
traverse(&l);
delvalofx(&l, 3);
traverse(&l);
return 0;
}
void initsqlist(psqlist pl) {//初始化
pl->pdata = (int*)malloc(sizeof(int)*pl->maxsize);
int a[10] = { 1,7,3,5,9,3,10,3,11 ,3};
for (int i = 0; i < 10; i++) {
pl->pdata[i] = a[i];
pl->length++;
}
return;
}
void traverse(psqlist pl) {//遍历
int i;
if (pl->length == 0) {
exit(-1);
}
for (i = 0; i < pl->length; i++) {
printf_s("%d ", pl->pdata[i]);
}
printf_s("\n");
}
void delvalofx(psqlist pl, int x) {
if (pl->length == 0)
exit(-1);
int k = 0;//用于记录所有等于x的数据元素个数
int i = 0;
while (i < pl->length) {
if (pl->pdata[i] == x) {
k++;
}
else {
pl->pdata[i - k] = pl->pdata[i];
}
i++;
}
pl->length = pl->length - k;
return;
}
方法二、用k记录所有不等于x的数据元素个数
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct SQList {
int * pData;
int length = 0;
int Maxsize = 15;
}SqList, *pSqList;
void Traverse(pSqList pL);//遍历
void InitSqlist(pSqList pL);//初始化
void DelValOfx2(pSqList pL, int x);//删除
int main(void) {
SqList L;
InitSqlist(&L);
Traverse(&L);
DelValOfx2(&L, 3);
Traverse(&L);
return 0;
}
void InitSqlist(pSqList pL) {//初始化
pL->pData = (int*)malloc(sizeof(int)*pL->Maxsize);
int a[10] = { 1,7,3,5,9,3,10,3,11 ,3 };
for (int i = 0; i < 10; i++) {
pL->pData[i] = a[i];
pL->length++;
}
return;
}
void Traverse(pSqList pL) {//遍历
int i;
if (pL->length == 0) {
exit(-1);
}
for (i = 0; i < pL->length; i++) {
printf_s("%d ", pL->pData[i]);
}
printf_s("\n");
}
void DelValOfx2(pSqList pL, int x) {
if (pL->length == 0)
exit(-1);
int k = 0;//用于记录所有不等于x的数据元素个数
int i = 0;
for (i; i < pL->length; i++) {
if (pL->pData[i] != x) {
pL->pData[k] = pL->pData[i];
k++;
}
}
pL->length = k;
return;
}
运行结果:
4、从有序顺序表中删除其值在给定值s和t之间(s<t)的所有元素,若s或t不合理或顺序表为空,则显示错误信息并退出运行。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct SQList {
int * pData;
int length = 0;
int Maxsize = 15;
}SqList, *pSqList;
void Traverse(pSqList pL);//遍历
void InitSqlist(pSqList pL);//初始化
void DelBetwST(pSqList pL, int s,int t);//删除3-7之间数据
int main(void) {
SqList L;
InitSqlist(&L);
Traverse(&L);
DelBetwST(&L, 3,7);
Traverse(&L);
return 0;
}
void InitSqlist(pSqList pL) {//初始化
pL->pData = (int*)malloc(sizeof(int)*pL->Maxsize);
int a[10] = { 1,3,3,4,4,5,6,7,8 ,9 };
for (int i = 0; i < 10; i++) {
pL->pData[i] = a[i];
pL->length++;
}
return;
}
void Traverse(pSqList pL) {//遍历
int i;
if (pL->length == 0) {
exit(-1);
}
for (i = 0; i < pL->length; i++) {
printf_s("%d ", pL->pData[i]);
}
printf_s("\n");
}
void DelBetwST(pSqList pL, int s, int t) {
if (s >= t ) {
printf_s("s或t值不合理\n");
exit(-1);
}
if (pL->length == 0) {
printf_s("顺序表为空\n");
exit(-1);
}
int i = 0, j = 0;
for (i; pL->pData[i] < s; i++);//用于定位到第一个大于等于s的位置
if (i > pL->length) {
printf_s("表中无此区间的数据存在\n");
exit(-1);
}
for (j; pL->pData[j] < t; j++);//用于定位到第一个大于等于t的位置
for (i, j; j < pL->length; i++, j++)
pL->pData[i] = pL->pData[j];
pL->length = i;
return;
}
运行结果:
5、从顺序表中删除其值在给定值S和t之间(包括s和t,s<t)的所有元素,若s或t不合理或顺序表为空,则显示出错误信息并退出运行。
#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct SQLIST {
int * pdata;
int length = 0;//有效数据长度
int Maxsize = 20;//申请空间(最大长度)
}SqList,*pSqList;
void InitSqList(pSqList pL);//初始化
void Traverse(pSqList pL);//遍历
void DelBetwst(pSqList pL,int s,int t);//删除
int main(void) {
SqList L;
InitSqList(&L);
Traverse(&L);
DelBetwst(&L,4,9);
printf_s("删除4到9之间的所有元素!\n");
Traverse(&L);
return 0;
}
void InitSqList(pSqList pL) {
pL->pdata = (int *)malloc(sizeof(int)*pL->Maxsize);
if (pL->pdata == NULL) {
printf_s("动态分配空间失败!\n");
exit(-1);
}
int a[15] = { 3,5,2,9,3,4,10,6,8,11,4,9,13,15,1 };
for (int i = 0; i < sizeof(a) / sizeof(int); i++) {
pL->pdata[i] = a[i];
pL->length++;
}
}
void Traverse(pSqList pL) {
int i = 0;
if (pL->length == 0) {
printf_s("表为空!\n");
exit(-1);
}
for(i;i<pL->length;i++){
printf_s("%d ", pL->pdata[i]);
}
printf_s("\n");
return;
}
void DelBetwst(pSqList pL,int s,int t) {
int k = 0;//记录在范围内的元素的个数
if (s >= t) {
printf_s("s或t输入不合法!\n");
exit(-1);
}
if (pL->length == 0) {
printf_s("表为空!\n");
exit(-1);
}
for (int i = 0; i < pL->length; i++) {
if (pL->pdata[i] >= s && pL->pdata[i] <= t)
k++;
else
pL->pdata[i - k] = pL->pdata[i];
}
pL->length = pL->length - k;
}
运行结果:
6、从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不相同。
#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct SQLIST {
int * pdata;
int length = 0;//有效数据长度
int Maxsize = 20;//申请空间(最大长度)
}SqList, *pSqList;
void InitSqList(pSqList pL);//初始化
void Traverse(pSqList pL);//遍历
void DelTheSames(pSqList pL);//删除
int main(void) {
SqList L;
InitSqList(&L);
Traverse(&L);
DelTheSames(&L);
printf_s("去重!\n");
Traverse(&L);
return 0;
}
void InitSqList(pSqList pL) {
pL->pdata = (int *)malloc(sizeof(int)*pL->Maxsize);
if (pL->pdata == NULL) {
printf_s("动态分配空间失败!\n");
exit(-1);
}
int a[10] = { 3,5,7,7,7,8,9,9,9,11 };
for (int i = 0; i < sizeof(a) / sizeof(int); i++) {
pL->pdata[i] = a[i];
pL->length++;
}
}
void Traverse(pSqList pL) {
int i = 0;
if (pL->length == 0) {
printf_s("表为空!\n");
exit(-1);
}
for (i; i < pL->length; i++) {
printf_s("%d ", pL->pdata[i]);
}
printf_s("\n");
return;
}
void DelTheSames(pSqList pL) {
int i, j;
if (pL->length == 0) {
printf_s("表为空!\n");
exit(-1);
}
for ( i = 0, j = 1; j < pL->length; j++) {
if (pL->pdata[i] != pL->pdata[j]) {//有序的顺序表,相同值一定相邻
i++; //第一个元素即pL->pdata[0]一定存在
pL->pdata[i] = pL->pdata[j];
}
}
pL->length = i + 1;
return;
}
运行结果:
7、将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表
#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct SQLIST {
int * pdata;
int length = 0;//有效数据长度
int Maxsize = 20;//申请空间(最大长度)
}SqList, *pSqList;
void InitSqList(pSqList pL1, pSqList pL2, pSqList pL3);//初始化
void Traverse(pSqList pL);//遍历
void MergeTwo(pSqList pL1, pSqList pL2, pSqList pL3);//合并两个表
int main(void) {
SqList L1,L2,L3;
InitSqList(&L1, &L2, &L3);
Traverse(&L1);
Traverse(&L2);
printf_s("合并:\n");
MergeTwo(&L1, &L2, &L3);
Traverse(&L3);
return 0;
}
void InitSqList(pSqList pL1, pSqList pL2, pSqList pL3) {
pL1->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
pL2->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
pL3->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
if (pL1->pdata == NULL) {
printf_s("pL1动态分配空间失败!\n");
exit(-1);
}
if (pL2->pdata == NULL) {
printf_s("pL2动态分配空间失败!\n");
exit(-1);
}
if (pL3->pdata == NULL) {
printf_s("pL3动态分配空间失败!\n");
exit(-1);
}
int a1[5] = { 2,3,4,6,8};
int a2[7] = { 3,5,6,7,8,9,15};
for (int i = 0; i < sizeof(a1) / sizeof(int); i++) {
pL1->pdata[i] = a1[i];
pL1->length++;
}
for (int i = 0; i < sizeof(a2) / sizeof(int); i++) {
pL2->pdata[i] = a2[i];
pL2->length++;
}
}
void Traverse(pSqList pL) {
int i = 0;
if (pL->length == 0) {
printf_s("表为空!\n");
exit(-1);
}
for (i; i < pL->length; i++) {
printf_s("%d ", pL->pdata[i]);
}
printf_s("\n");
return;
}
void MergeTwo(pSqList pL1, pSqList pL2, pSqList pL3) {
int i=0, j=0,k=0;
if ((pL1->length + pL2->length) > pL3->Maxsize) {
printf_s("两个表长度之和超出最大范围!\n");
exit(-1);
}
while (i < pL1->length&&j < pL2->length) {
if (pL1->pdata[i] <= pL2->pdata[j])
pL3->pdata[k++] = pL1->pdata[i++];
else
pL3->pdata[k++] = pL2->pdata[j++];
}
while (i < pL1->length) {
pL3->pdata[k++] = pL1->pdata[i++];
}
while (j < pL2->length) {
pL3->pdata[k++] = pL2->pdata[j++];
}
pL3->length = k;
return;
}
运行结果:
8、题目8:已知一维数组A[m+n]中依次存放两个线性表(a1,a2,,am),和(b1,b2,,,bn)。试编写一个函数,将数组中两个顺序表的位置互换,即将(b1,b2,,,bn)放在(a1,a2,,am)前面。
#include <stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct SQLIST {
int * pdata;
int length = 0;//有效数据长度
int Maxsize = 20;//申请空间(最大长度)
}SqList, *pSqList;
void InitSqList(pSqList pL1, pSqList pL2, pSqList pL3);//初始化
void Traverse(pSqList pL);//遍历
void MergeTwo(pSqList pL1, pSqList pL2, pSqList pL3);//合并两个表
int GetLength(pSqList pL);//获取顺序表的长度
void Reverse(pSqList pL, int left, int right);//倒置
int main(void) {
SqList L1, L2, L3;
InitSqList(&L1, &L2, &L3);
printf_s("L1: ");
Traverse(&L1);
printf_s("L2: ");
Traverse(&L2);
printf_s("合并L3: ");
MergeTwo(&L1, &L2, &L3);
Traverse(&L3);
int m = GetLength(&L1);
int n = GetLength(&L2);
printf_s("实现L1和L2位置的交换:\n");
Reverse(&L3, 0, m + n - 1);
Reverse(&L3, 0, n - 1);/*第一次整体倒置后,前m个现在是后m个并为倒置的;
原第二部分即后n个现在是前n个,且为倒置的,此时要分别把两部分的次
序恢复,此时的第一部分再倒置一次,第二部分在倒置一次。
*/
Reverse(&L3, n, m + n - 1);
Traverse(&L3);
return 0;
}
void InitSqList(pSqList pL1, pSqList pL2, pSqList pL3) {
pL1->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
pL2->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
pL3->pdata = (int *)malloc(sizeof(int)*pL1->Maxsize);
if (pL1->pdata == NULL) {
printf_s("pL1动态分配空间失败!\n");
exit(-1);
}
if (pL2->pdata == NULL) {
printf_s("pL2动态分配空间失败!\n");
exit(-1);
}
if (pL3->pdata == NULL) {
printf_s("pL3动态分配空间失败!\n");
exit(-1);
}
int a1[5] = { 1,2,3,4,5 };
int a2[7] = { 6,7,8,9,10,11,12 };
for (int i = 0; i < sizeof(a1) / sizeof(int); i++) {
pL1->pdata[i] = a1[i];
pL1->length++;
}
for (int i = 0; i < sizeof(a2) / sizeof(int); i++) {
pL2->pdata[i] = a2[i];
pL2->length++;
}
}
void Traverse(pSqList pL) {
int i = 0;
if (pL->length == 0) {
printf_s("表为空!\n");
exit(-1);
}
for (i; i < pL->length; i++) {
printf_s("%d ", pL->pdata[i]);
}
printf_s("\n");
return;
}
void MergeTwo(pSqList pL1, pSqList pL2, pSqList pL3) {
int i = 0, j = 0, k = 0;
if ((pL1->length + pL2->length) > pL3->Maxsize) {
printf_s("两个表长度之和超出最大范围!\n");
exit(-1);
}
while (i < pL1->length&&j < pL2->length) {
if (pL1->pdata[i] <= pL2->pdata[j])
pL3->pdata[k++] = pL1->pdata[i++];
else
pL3->pdata[k++] = pL2->pdata[j++];
}
while (i < pL1->length) {
pL3->pdata[k++] = pL1->pdata[i++];
}
while (j < pL2->length) {
pL3->pdata[k++] = pL2->pdata[j++];
}
pL3->length = k;
return;
}
int GetLength(pSqList pL) {
int l = pL->length;
return l;
}
void Reverse(pSqList pL, int left, int right) {
if (pL->length == 0) {
printf_s("顺序表为空!\n");
exit(-1);
}
int i = left, j = right;
int t = 0;
for (i, j; i < j; i++, j--) {
t = pL->pdata[i];
pL->pdata[i] = pL->pdata[j];
pL->pdata[j] = t;
}
}
运行结果: