#include<stdio.h>
#define Maxsize 50
typedef struct{
int data[Maxsize];
int length;
} Seqlist;
#pragma region 基础操作
//插入多个元素
void InsertElements(Seqlist *seq,int data[],int count)
{
for (int i = 0; i < count; i++)
{
seq->data[i] = data[i];
seq->length ++;
}
}
void InitSeqlist(Seqlist *seq)
{
seq->length=0;
}
int InsertElement(Seqlist *seq,int pos,int x)
{
//超出范围
if (seq->length>Maxsize) return 0;
//如果不满足条件说明是尾插,直接跳过for循环进入赋值阶段
for (int i = seq->length-1; i > pos-1; i--)
{
seq->data[i+1]=seq->data[i];
}
seq->data[pos]=x;
seq->length++;
return 1;
}
void ShowSeqlist(Seqlist seq)
{
printf("------------------------------\n");
for (int i = 0; i < seq.length; i++)
{
printf("the %d position is %d\n",i+1,seq.data[i]);
}
printf("------------------------------\n");
}
int DeleteElement(Seqlist *seq,int pos)
{
if(seq->length==0) return -1;
//这个数据通过指针返回
int tem=seq->data[pos];
for (int i = pos; i < seq->length-1; i++)
{
seq->data[i]=seq->data[i+1];
}
seq->length--;
return tem;
}
int FindByContent(Seqlist *seq,int con)
{
for (int i = 0; i < seq->length; i++)
{
if(seq->data[i]==con) return i;
}
return -1;
}
#pragma endregion
#pragma region 逆序问题
/**
* Q1
* 将一长度为n的数组的前端k个元素逆序后移动到数组后段,要求原数组元素不丢失,其余元素位置无关紧要。
* 将数据整体逆序就可以
*/
int Reverse(Seqlist *seq,int begin,int end)
{
if (begin<0||begin>seq->length-1||end<begin||end>seq->length-1) return 0;
//左右指针
int left=begin,right=end;
//缓存
int tem;
//这个条件很重要
while((right!=left)&&(right>left))
{
tem=seq->data[right];
seq->data[right]=seq->data[left];
seq->data[left]=tem;
right--;
left++;
}
return 1;
}
/*
* 将一长度为n的数组的前段k个元素保持原顺序移动到数组后段,要求数据不丢失,且其他元素的位置无所谓
* 1 2 3 4 5 6 7 8 9 10 k=3 前k个逆序
* 3 2 1 4 5 6 7 8 9 10 整体逆序
* 10 9 8 7 6 5 1 2 3 4 得到答案
**/
int Q2(Seqlist *seq,int k)
{
return Reverse(seq,0,k)&&Reverse(seq,0,seq->length-1);;
}
/**
* 数组循环左移p位
* 1 2 3 4 5 6 7 8 9 10 k=3 前p个逆序
* 3 2 1 10 9 8 7 6 5 4 p-length-1逆序
* 4 5 6 7 8 9 10 1 2 3 整体逆序
*/
int Q3(Seqlist *seq,int p)
{
Reverse(seq,0,p)&&Reverse(seq,p+1,seq->length-1);
Reverse(seq,0,9);
return 0;
}
#pragma endregion
#pragma region 王道顺序表大题
//从此往下4个题目都很相似,其思想就算顺序表边查找便删除
//也就是某些元素满足某一个条件需要删掉,设置一个计数器记录该元素的个数
//后面元素移动计数器个个数即可删除掉满足条件的元素
//最后别忘了length减去count
/**
* 对于一个长度为n的顺序表x,编写一个时间复杂度为on,空间复杂度为o1的算法,该算法
* 删除线性表中所有值为x的数据元素。
* input: 1 2 3 4 3 5 8 6 3 4 1 2 4 3 5 4
* output:1 2 4 5 8 6 4 1 2 4 5 4
* Test:
* Seqlist wang;
InitSeqlist(&wang);
int data[]={1,2,3,4,3,5,8,6,3,4,1,2,4,3,5,4};
InsertElements(&wang,data,sizeof(data)/sizeof(int));
DeleteX(&wang,3);
ShowSeqlist(wang);
*/
void DeleteX(Seqlist *seq,int x)
{
int count=0;
for (int i = 0; i < seq->length; i++)
{
if (seq->data[i]==x)
{
count++;
continue;
}
seq->data[i-count]=seq->data[i];
}
seq->length-=count;
}
/**
* 从有序顺序表中删除其值在给定值s与t之间的(要求s<t)的所有元素,如果s或t不合理或者顺序表位空,则显示错误信息并退出
* input: 1 2 3 4 5 6 7 8 9 10 s=3 t=7
* output:1 2 3 7 8 9 10
* test:
* Seqlist wang;
InitSeqlist(&wang);
for (int i = 0; i < 10; i++)
{
InsertElement(&wang,i,i+1);
}
DeleteBetwenST(&wang,3,7);
ShowSeqlist(wang);
*/
int DeleteBetwenST(Seqlist *seq ,int s,int t)
{
if((s>t)||s==t||seq->length==0||s<1||t>seq->length) return -1;
int count=0;
for (int i = 0; i < seq->length; i++)
{
if (seq->data[i]>s&&seq->data[i]<t)
{
count++;
continue;
}
seq->data[i-count]=seq->data[i];
}
seq->length-=count;
return 1;
}
/**
* 从顺序表中删除其值在st之间包含st要求s<t的所有元素,如果s或t不合理或顺序表为空,返回错误信息
* s=3 t=5
* input: 1 2 3 4 3 5 8 6 3 4 1 2 4 3 5 4
* output: 1 2 8 6 1 2
* test:
* Seqlist wang;
InitSeqlist(&wang);
int data[]={1,2,3,4,3,5,8,6,3,4,1,2,4,3,5,4};
InsertElements(&wang,data,sizeof(data)/sizeof(int));
DeleteST(&wang,3,5);
ShowSeqlist(wang);
*/
int DeleteST(Seqlist *seq,int s,int t)
{
if((s>t)||s==t||seq->length==0||s<1||t>seq->length) return -1;
int count=0;
for (int i = 0; i < seq->length; i++)
{
if ((seq->data[i]>s||seq->data[i]==s)&&(seq->data[i]<t||seq->data[i]==t))
{
count++;
continue;
}
seq->data[i-count]=seq->data[i];
}
seq->length-=count;
return 1;
}
/**
* 从有序顺序表中删除所有其值重复的元素,使表中的所有元素均不相同
*
*/
int DeleteSameElement(Seqlist *seq)
{
int count=0;
for (int i = 0; i < seq->length; i++)
{
if (seq->data[i]==seq->data[i+1])
{
count++;
continue;
}
seq->data[i-count]=seq->data[i];
}
seq->length-=count;
}
//合并顺序表
/**
* 将两个有序顺序表合并成一个新的有序顺序表,并有函数返回结果
* 1 2 4 5 7 9
* 4 8 10 12 14 22 31
* 1 2 4 4 5 7 8 9 10 12 14 22 31
* test:
* Seqlist wang,w1,w2;
InitSeqlist(&wang);
InitSeqlist(&w1);
InitSeqlist(&w2);
int a[6]={1,2,4,5,7,9};
InsertElements(&w1,a,sizeof(a)/sizeof(int));
int b[7]={4,8,10,12,14,22,31};
InsertElements(&w2,b,sizeof(b)/sizeof(int));
AddSeqList(&w1,&w2,&wang);
ShowSeqlist(wang);
*/
int AddSeqList(Seqlist *src,Seqlist * dir,Seqlist * result)
{
//没有空间可以容纳
if((src->length+dir->length)>Maxsize) return -1;
//设置两个指针分别指向顺序表12的开头
int ps=0,pd=0,i=0;
//当其中一个指针指向末尾则结束,不能往下继续
//因为有一个++后越界
while(ps!=(src->length)&&(pd!=dir->length))
{
if (src->data[ps]<dir->data[pd])
{
result->data[i]=src->data[ps];
i++;ps++;
result->length++;
continue;
}
else
{
result->data[i]=dir->data[pd];
pd++;i++;
result->length++;
continue;
}
}
//不可能大于
for (;ps < src->length;i++,ps++)
{
result->data[i]=src->data[ps];
result->length++;
}
for (;pd < dir->length;i++,pd++)
{
result->data[i]=dir->data[pd];
result->length++;
}
return 0;
}
/**
* 线性表a1 a2 ... an 中元素递增且有序存储于计算机内部,要求设计一算法
* 完成用最少的时间查找数值为x的元素,若找到则将其与其后继元素交换位置,若找不到
* 则将其插入表中并使得表中元素仍递增有序。
* 1 2 3 4 5 7 8 9 10
*/
int Findx(Seqlist *seq,int x)
{
int pos=0;
for (int i = 0; i < seq->length; i++)
{
if (seq->data[i]==x)
{
//最后一个元素没有后继元素。
if(i==seq->length-1) return -1;
seq->data[i]=seq->data[i+1];
seq->data[i+1]=x;
return 1;
}
else if(seq->data[i]>x)
{
//没有空间容纳
if (seq->length+1>Maxsize) return -1;
for (int j = seq->length;j>i-1; j--)
{
seq->data[j]=seq->data[j-1];
}
seq->data[i]=x;
return 1;
}
}
//x不再该序列范围内
return -1;
}
int FindMiddleNum(Seqlist *src,Seqlist *dir)
{
Seqlist result;
InitSeqlist(&result);
AddSeqList(src,dir,&result);
if (result.length%2==0)
{
int i=(result.length)/2-1,j=result.length/2;
return (result.data[i]+result.data[j])/2;
}
else
{
int i=(result.length+1)/2-1;
return result.data[i];
}
}
//暂时不会
//2013.12题
int FindMainElement(Seqlist *seq);
int FindMissMinNum(Seqlist *seq,int n)
{
int num=1;
int count[n];
for (int i = 0; i < n; i++)
{
count[i]=0;
}
for (int i = 0; i < seq->length; i++)
{
if (seq->data[i]>0&&seq->data[i]<n) count[seq->data[i]-1]=1;
}
int k=0;
for (k = 0; k < n; k++)
{
if(count[k]==0) break;
}
return k+1;
}
#pragma endregion
int main()
{
Seqlist seq;
InitSeqlist(&seq);
for (int i = 0; i < 5; i++)
{
InsertElement(&seq,i,i);
}
ShowSeqlist(seq);
InsertElement(&seq,2,8);
ShowSeqlist(seq);
int x=DeleteElement(&seq,3);
printf("be deletd x is %d\n",x);
ShowSeqlist(seq);
int pos=FindByContent(&seq,8);
printf("x is positioned on %d\n",pos);
printf("逆序前\n");
ShowSeqlist(seq);
Reverse(&seq,0,seq.length-1);
printf("逆序后\n");
ShowSeqlist(seq);
printf("逆序前\n");
ShowSeqlist(seq);
Q2(&seq,2);
Seqlist bigseq;
InitSeqlist(&bigseq);
for (int i = 0; i < 10; i++)
{
InsertElement(&bigseq,i,i+1);
}
printf("逆序前\n");
ShowSeqlist(bigseq);
Q3(&bigseq,3);
printf("逆序后\n");
ShowSeqlist(bigseq);
Seqlist wang,w1,w2;
InitSeqlist(&wang);
int a[9]={1,2,3,4,5,7,8,9,10};
InsertElements(&wang,a,sizeof(a)/sizeof(int));
Findx(&wang,7);
ShowSeqlist(wang);
}
数据结构之王道顺序表大题
最新推荐文章于 2024-08-17 22:18:48 发布