408 数据结构
顺序表代码题
我目前写的这些题基本上都是冲刺必会代码100题里面的,后续应该会补充在写王道大题时遇到的一些真题和好题。
一些函数还有传参时用到的函数我没有在这篇文章中写,有需要的可以复制一下我上一篇文章的代码。
1 已知线性表(a1 a2 ----an)按顺序结构存储且每个元素为不相等的整数。设计把所有奇数挪到所有偶数前面的算法。(要求时间最少 辅助空间最少)
void Moveodd(seqlist* L)
{
//前后相互遍历的思想
int i = 0, j = L->length - 1;
ElementType temp;
while (i <= j)
{
//奇数
if (L->data[i] % 2 == 1)
i++;
//偶数在后面
if (L->data[j] % 2 == 0)
j--;
if (L->data[i] % 2 == 0 && L->data[j] % 2 == 1)
{
temp = L->data[j];
L->data[j] = L->data[i];
L->data[i] = temp;
i++;
j--;
}
}
}
2 设计一个高效算法 将顺序表L中所有元素逆置,要求算法的空间复杂度为O(1)
void Reverse(seqlist* L)
{
ElementType temp;
//如果L->length 长度 为8 的话 占用了0-7 数字下标小宇 这个4即可 0123 前面四个和后面四个对比
// 长度为9 0-8 小于4 0123 4 5678 前四个和后四个交换位置 中间这个不动
for (int i = 0; i < (L->length) / 2; i++)
{
temp = L->data[i];
L->data[i] = L->data[L->length - 1 - i];
L->data[L->length - 1 - i] = temp;
}
}
3 两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表。
void Merge(seqlist* L, seqlist* X,seqlist* C)
{
//两个表都是有序表 对比他俩的第一个元素 谁小谁先放前面。
int i = 0;
int j = 0;
int k = 0;
//怎么说呢 得先比较这个length吧 要是length加一起超过了最大长度 那肯定不能合并了
if (L->length + X->length > List_size)
{
printf("这两个顺序表的长度加起来大于最大长度! 无法合并");
}
//任何一个顺序表要是对比完了 他就不能接着在这里面比较了 他用完了 对面的就全接在后面了
while (i < L->length && j < X->length)
{
//比大小 小的放前面
if (L->data[i] < X->data[j])
{
C->data[k] = L->data[i];
i++;
k++;
}
else
{
C->data[k] = X->data[j];
j++;
k++;
}
}
//程序运行到这里的时候 肯定有一个已经比完了
if (i == L->length)
{
while (j != X->length)
{
C->data[k] = X->data[j];
j++;
k++;
}
}
if (j == X->length)
{
while (i != L->length)
{
C->data[k] = L->data[i];
i++;
k++;
}
}
C->length = k;
printf("C数组的长%d L%d X%d \n", k, L->length, X->length);
}
4 从顺序表中删除最小的元素(假设唯一),并由函数返回被删除元素的值。空出的元素由最后一个元素填补。
ElementType Delete_min(seqlist * L)
{
int flag=0;
int min =10000;
for (int i = 0; i < L->length; i++)
{
if (L->data[i] < min)
{
flag = i;
min = L->data[i];
}
}
L->data[flag] = L->data[L->length - 1];
L->length--;
return min;
}
5 已知长度为n的线性表L采用顺序存储结构,编写空间复杂度为O(1)的算法,该算法删除线性表中所有值在x到y(x<=y)之间的数据元素。
个人感觉题目说的不清楚 你空出来的元素是用最后一个元素补上呢 还是后面依次填上来
void Delete_xy(seqlist* L, ElementType x, ElementType y)
{
int k = 0;
for (int i = 0; i < L->length; i++)
{
//不需要被删除的数据 依次排开
if (!(L->data[i] >= x && L->data[i] <= y))
{
L->data[k] = L->data[i];
k++;
}
}
L->length = k;
}
6 [2010年统考]设将n(n>1个整数)存放在一维数组R中。试设计一个时间复杂度和空间复杂度都尽可能高校的算法,将R中保存的序列循环左移p位(0<p<n)个位置,即将R中的数据由(X0,X1...X(n-1))变换为(Xp,Xp+1,....Xn-1,X0,X1,....,Xp-1)要求:1 给出算法的基本设计思想 2 根据算法设计思想采用C语言描述,关键之处给出注释 3 说明你所设计的算法的时间复杂度和空间复杂度。
下面分别贴出我一开始写的代码和标准代码
void LeftMove(seqlist* R, seqlist* L, int p)
{
//存放左移溢出的数据
for (int i = 0; i < p; i++)
{
L->data[i] = R->data[i];
}
for (int i = p; i < R->length; i++)
{
R->data[i - p] = R->data[i];
}
for (int i = 0; i < p; i++)
{
R->data[i + p] = L->data[i];
}
}
标准答案
//给一个数组 他会把里面的数据原地逆置 你得划定一个范围
void New_Reverse(seqlist* L, int left, int right)
{
int i = left;
int j = right;
while (i < j)
{
ElementType temp=L->data[j];
L->data[j] = L->data[i];
L->data[i] = temp;
i++;
j--;
}
}
//标准答案左移
void LeftShift(seqlist* L, int p)
{
if (p > 0 && p < L->length)
{
//全部逆置
New_Reverse(L, 0, L->length - 1);
//逆置前面n-p个
New_Reverse(L, 0, L->length - 1 - p);
//逆置后面的p个
New_Reverse(L, L->length - p, L->length - 1);
}
}
测试这些函数用的main函数
int main() {
/*ElementType x ;*/
seqlist L,X,C;
InitList(&L);
InitList(&X);
InitList(&C);
//为什么啊 还是指针不熟悉我感觉
Insert(&L, 1, 10);
Insert(&L, 1, 9);
Insert(&L, 1, 8);
Insert(&L, 1, 7);
Insert(&L, 1, 100);
Insert(&L, 1, 20);
Insert(&L, 1, 17);
Insert(&L, 1, 19);
PrintList(&L);
printf("找出最小值:\n");
int min=Delete_min(&L);
printf("min是%d\n", min);
PrintList(&L);
printf("左移4位\n");
/*LeftMove(&L, &C, 4);*/
LeftShift(&L, 4);
PrintList(&L);
printf("删除10-100 内的数字\n");
Delete_xy(&L, 10, 100);
PrintList(&L);
Insert(&X, 1, 8);
Insert(&X, 1, 44);
Insert(&X, 1, 76);
Insert(&X, 1, 200);
Insert(&X, 1, 123);
Insert(&X, 1, 5);
Insert(&X, 1, 11);
Insert(&X, 1,888);
printf("另一个队列\n");
PrintList(&X);
Sort(&X,0,X.length-1);
PrintList(&X);
printf("排序前\n");
PrintList(&L);
//printf("删除的这个数是 %d\n",x);
/*printf("%d\n",Findlocate(&L, 2));*/
Moveodd(&L);
printf("排序后\n");
PrintList(&L);
Reverse(&L);
PrintList(&L);
printf("快排开始\n");
Sort(&L, 0, L.length-1);
printf("快排结束\n");
PrintList(&L);
printf("-----------------------------------------\n");
Merge(&L, &X, &C);
PrintList(&L);
PrintList(&X);
PrintList(&C);
//Insert(L, 2, 20);
//PrintList(L);
//Insert(L, 1, 8);
//PrintList(L);
//Insert(L, 1, 9);
//PrintList(L);
//Insert(L, 1, 7);
//PrintList(L);
//Delete(L, 1, x);
//PrintList(L);
//PrintList(L);
//
return 0;
}