线性表,全名为线性存储结构。将具有“一对一”关系的数据“线性”地存储到物理空间中,这种存储结构就称为线性存储结构(简称线性表)。
顺序表,全名顺序存储结构。将数据依次存储在连续的整块物理空间中,这种存储结构称为顺序表,即逻辑上相邻的元素在物理上也是相邻的。
顺序表的初始化
使用顺序表存储数据之前,除了要申请足够大小的物理空间之外,为了方便后期使用表中的数据,顺序表还需要实时记录以下 2 项数据:
- 顺序表申请的存储容量;
- 顺序表的长度,也就是表中存储数据元素的个数;
首先自定义顺序表。
#define MaxSize 50
#define Error 0
typedef int ElemType;
typedef struct SqList{
ElemType data[MaxSize];
int Length;
}SeqList, *pSeqList;
注意这里定义了一个MaxSize用来指明顺序表申请的存储容量, Length指明表中数据元素的个数。
接着初始化顺序表。
//初始化
void InitSeqList(pSeqList psqlt) {
assert(NULL != psqlt);
memset(psqlt->data, 0, sizeof(ElemType)*MaxSize);
psqlt->Length = 0;
}
顺序表插入元素
尾插,时间复杂度O(1), 总是从顺序表的末尾插入,没有元素的移动。
//尾插
void InsertLast(pSeqList psqlt, ElemType e) {
assert(NULL != psqlt);
if (psqlt->Length == MaxSize) {
printf("SeqList is FULL.......\n");
return;
}
psqlt->data[psqlt->Length++] = e;
}
首插, 总是将新元素插入到顺序表的首地址位置,需要将顺序表的Length个元素往后移动一个位置,时间复杂度O(n)。
//首插
void InsertFront(pSeqList psqlt, ElemType e) {
assert(NULL != psqlt);
if (psqlt->Length == MaxSize) {
printf("SeqList is FULL....\n");
}
for (int i=psqlt->Length; i>0; i--) {
psqlt->data[i] = psqlt->data[i-1];
}
psqlt->data[0] = e;
psqlt->Length ++;
}
在指定位置插入
1.通过遍历,找到数据元素要插入的位置
2.将要插入位置元素以及后续的元素整体向后移动一个位置
3.将元素放到腾出来的位置
//在指定位置i插入e
void Insert(pSeqList psqlt, ElemType e, int p) {
assert(NULL != psqlt);
if (psqlt->Length == MaxSize) {
printf("SeqList is Full....\n");
return;
}
if (psqlt->Length == 0) {
printf("SeqList if Empty....\n");
p = 1;
}
for (int i=psqlt->Length; i>=p; i--) {
psqlt->data[i] = psqlt->data[i-1];
}
psqlt->data[p-1] = e;
psqlt->Length ++;
}
顺序表删除元素
尾删, 总是从顺序表的尾部开始删除元素,时间复杂度为O(1), 没有元素的移动。
//尾删
void PopLast(pSeqList psqlt) {
assert(NULL != psqlt);
if (psqlt->Length == 0) {
printf("SeqList is empty....\n");
return;
}
psqlt->Length --;
}
首删, 总是从顺序表的首地址开始删除元素,将其后的Length-1个元素都需要向前移动一位置, 时间复杂度为O(n)。
//首删
void PopFront(pSeqList psqlt) {
assert(NULL != psqlt);
if (psqlt->Length == 0) {
printf("Seqlist is Empty......\n");
return;
}
for (int i=0; i<psqlt->Length; i++) {
psqlt->data[i] = psqlt->data[i+1];
}
psqlt->Length --;
}
在指定位置删除
只需找到目标元素,并将其后续所有元素整体前移 1 个位置即可。(后续元素整体前移一个位置,会直接将目标元素删除,可间接实现删除元素的目的。)
//删除指定位置i的数
void Pop(pSeqList psqlt, int p) {
assert(NULL != psqlt);
if (psqlt->Length == 0) {
printf("SeqList if Empty....\n");
return;
}
if (p > psqlt->Length || p < 1) {
printf("not exixet...\n");
}
for (int i=p-1; i<psqlt->Length; i++) {
psqlt->data[i] = psqlt->data[i+1];
}
psqlt->Length--;
}
逆置
//逆置
void Reverse(pSeqList psqlt) {
assert(NULL != psqlt);
int start = 0;
int end = psqlt->Length - 1;
while (start != end) {
int temp = psqlt->data[start];
psqlt->data[start] = psqlt->data[end];
psqlt->data[end] = temp;
start ++;
end --;
}
}
有序表删除重复元素
//有序表删除所有值重复的元素
void DeleteRepeat(pSeqList psqlt) {
assert(NULL != psqlt);
if (psqlt->Length == 0) {
printf("SeqList is Empty....\n");
return;
}
for (int i=0; i<psqlt->Length; i++) {
if (psqlt->data[i] == psqlt->data[i+1]) {
if (psqlt->data[0] == psqlt->data[1]) {
for (int j=0; j<psqlt->Length; j++) {
psqlt->data[j] = psqlt->data[j+1];
}
psqlt->Length --;
}
for (int j=i; j<psqlt->Length; j++) {
psqlt->data[j] = psqlt->data[j+1];
}
psqlt->Length --;
}
}
}
有序表拼接
//有序表拼接 s1+s2
void SeqlistJoin(pSeqList ps1, pSeqList ps2, pSeqList psqlt) {
assert(NULL != ps1);
assert(NULL != ps2);
if (ps1->Length == 0 || ps2->Length == 0) {
printf("Seqlist is Empty...\n");
return;
}
if (ps1->Length + ps2->Length > MaxSize) {
printf("Seqlist is Full...\n");
return;
}
int i=0, j=0, k=0;
while (i<ps1->Length && j<ps2->Length) {
if (ps1->data[i] <= ps2->data[j]) {
psqlt->data[k++] = ps1->data[i++];
}
else {
psqlt->data[k++] = ps2->data[j++];
}
}
while (i<ps1->Length) {
psqlt->data[k++] = ps1->data[i++];
}
while (j<ps2->Length) {
psqlt->data[k++] = ps2->data[j++];
}
psqlt->Length = k;
}
循环右移p个单位
//循环右移p个单位
void MoveP(pSeqList psqlt, int p) {
assert(psqlt);
pSeqList new;
new = (SeqList *)malloc(sizeof(SeqList));
for (int i=0; i<p-1; i++) {
new->data[i] = psqlt->data[i];
new->Length ++;
}
int j=p-1;
for (int i=0; i<=p; i++) {
psqlt->data[i] = psqlt->data[j];
j++;
}
int k = p;
for (int i=0; i<p; i++) {
psqlt->data[k] = new->data[i];
k++;
}
}
找出list1和list2的中位数
//找出中位数
int M_Search(pSeqList list1, pSeqList list2) {
assert(list1);
assert(list2);
int s1=0, d1=list1->Length-1, m1, s2=0, d2=list2->Length-1, m2;
while (s1!=d1 || s2!=d2) {
m1 = (s1+d1)/2;
m2 = (s2+d2)/2;
if (list1->data[m1] == list2->data[m2]) {
return list2->data[m1];
}
if (list1->data[m1] < list2->data[m2]) {
if ((s1+d1)%2 == 0) {
s1 = m1;
d2 = m2;
}
else {
s1 = m1+1;
d2 = m2;
}
}
else {
if ((s2+d2)%2 == 0) {
d1 = m1;
s2 = m2;
}
else {
d1 = m1;
s2 = m2+1;
}
}
}
return list1->data[s1]<list2->data[s2]?list1->data[s1]:list2->data[s2];
}
找出主元素
1> 有这样的一组数列, 假设数列的第一个数是主元素, 我们就计作主元素个数为1, 假设下一个元素等于主元素,计数+1,如果不是,计数-1, 当计数为0是, 我们就把当前这个数计做主元素
2>如果计数>数组长度的一半,就表示找到了主元素, 否则没找到
//找出主元素
int Majority(pSeqList list) {
int c, count=0;
c = list->data[0];
for (int i=1; i<list->Length; i++) {
if (list->data[i] == c) {
count ++;
}
if (list->data[i] != c && count>0) {
count --;
}
else {
c = list->data[i];
count = 1;
}
}
count = 0;
for (int i=0; i<list->Length; i++) {
if (list->data[i] == c) {
count ++;
}
}
if (count > list->Length/2) {
return c;
}
return -1;
}
找出未出现的最小正整数
//找出未出现的最小正整数
int FindMissMin(pSeqList list) {
pSeqList new = (SeqList *)malloc(sizeof(SeqList));
pSeqList flagnew = (SeqList *)malloc(sizeof(SeqList));
for (int i=0; i<list->Length; i++) {
new->data[i] = i+1;
new->Length ++;
if (new->data[i] == list->data[i]) {
flagnew->data[i] = 0;
flagnew->Length ++;
}
if(new->data[i] < list->data[i]) {
flagnew->data[i] = 1;
flagnew->Length ++;
}
}
for (int i=0; i<list->Length; i++) {
if (flagnew->data[i] == 1) {
return new->data[i];
}
}
return new->data[new->Length-1]+1;
}
测试
void testSequlist() {
SeqList list;
SeqList list2;
InitSeqList(&list);
InitSeqList(&list2);
SeqList list3;
InitSeqList(&list3);
SeqList list4;
InitSeqList(&list4);
InsertLast(&list, 34);
PrintSeqList(list);
InsertFront(&list, 20);
PrintSeqList(list);
PopLast(&list);
PrintSeqList(list);
PopFront(&list);
PrintSeqList(list);
Insert(&list, 23, 1);
PrintSeqList(list);
Pop(&list, 1);
PrintSeqList(list);
InsertLast(&list, 11);
InsertLast(&list, 13);
InsertLast(&list, 15);
InsertLast(&list, 17);
InsertLast(&list, 19);
PrintSeqList(list);
InsertLast(&list2, 2);
InsertLast(&list2, 4);
InsertLast(&list2, 6);
InsertLast(&list2, 8);
InsertLast(&list2, 20);
PrintSeqList(list2);
// MoveP(&list, 3);
// PrintSeqList(list);
printf("%d\n", M_Search(&list, &list2));
InsertLast(&list3, 0);
InsertLast(&list3, 5);
InsertLast(&list3, 5);
InsertLast(&list3, 3);
InsertLast(&list3, 5);
InsertLast(&list3, 7);
InsertLast(&list3, 5);
InsertLast(&list3, 7);
PrintSeqList(list3);
printf("%d\n", Majority(&list3));
printf("FindMissMin...\n");
InsertLast(&list4, 1);
InsertLast(&list4, 2);
InsertLast(&list4, 3);
InsertLast(&list4, 4);
InsertLast(&list4, 5);
InsertLast(&list4, 6);
InsertLast(&list4, 7);
InsertLast(&list4, 9);
printf("%d\n", FindMissMin(&list4));
}