数据结构顺序表——链表
Posted Huang_ZhenSheng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构顺序表——链表相关的知识,希望对你有一定的参考价值。
目录
顺序表
可动态增长的数组,要求数据是连续存储的
(类似通讯录,本文直接上代码哦)
头文件SeqList.h:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SQDataType;
typedef struct SeqList
{
SQDataType* a;
int size;//有效数据的个数
int capacity;//容量空间的大小
}SLT;
//增删查改
void SeqListInit(SLT* ps1);//初始化
void SeqListDestory(SLT* ps1);
void SeqListPushBack(SLT* ps1, SQDataType x);
void SeqListPushfront(SLT* ps1, SQDataType x);
void SeqListPrint(SLT* Ps1);
void SeqListCheckCapacity(SLT* ps1);
//尾插尾删,头插头删
void SeqListPushBack(SLT* ps1, SQDataType x);//时间复杂度O(1)
void SeqListPushFront(SLT* ps1,SQDataType x);//时间复杂度O(N)
void SeqListPopBack(SLT* ps1);//时间复杂度O(1)
void SeqListPopFront(SLT* ps1);//时间复杂度O(N)
测试文件8.6.c:
#include"SeqList.h"
void TestSeqList()
{
SLT s;
SeqListInit(&s);
SeqListCheckCapacity(&s);
SeqListPushBack(&s, 1);//尾插
SeqListPushBack(&s, 2);//尾插
SeqListPushBack(&s, 3);//尾插
SeqListPrint(&s);
SeqListPushFront(&s, -1);//头插
SeqListPrint(&s);
SeqListPopBack(&s);//尾删
SeqListPrint(&s);
SeqListPopFront(&s);//头删
SeqListPrint(&s);
SeqListPopFront(&s);//头删
SeqListPrint(&s);
SeqListPopFront(&s);//头删
SeqListPrint(&s);
SeqListDestory(&s);
}
int main()
{
TestSeqList();
return 0;
}
文件运行SeqList.c:
#include"SeqList.h"
void SeqListInit(SLT* ps1)
{
assert(ps1);
ps1->a = NULL;
ps1->size = ps1->capacity = 0;
}
void SeqListDestory(SLT* ps1)
{
assert(ps1);
if (ps1->a)
{
free(ps1->a);
ps1->a = NULL;
}
ps1->size = ps1->capacity = 0;
}
void SeqListPrint(SLT* ps1)
{
assert(ps1);
for (int i = 0; i < ps1->size; i++)
{
printf(" %d",ps1->a[i]);
}
printf("\\n");
}
//是否满了,满了就要增容
void SeqListCheckCapacity(SLT* ps1)
{
assert(ps1);
if (ps1->size == ps1->capacity)
{
size_t newcapacity = ps1->capacity == 0 ? 4 : ps1->capacity * 2;
ps1->a = (SQDataType*)realloc(ps1->a, newcapacity*sizeof(SQDataType));
ps1->capacity = newcapacity;
}
}
//尾插尾删,头插头删
void SeqListPushBack(SLT* ps1, SQDataType x)//尾插
{
assert(ps1);
SeqListCheckCapacity(ps1);
ps1->a[ps1->size] = x;
ps1->size++;
}
void SeqListPushFront(SLT* ps1, SQDataType x)//头插
{
assert(ps1);
SeqListCheckCapacity(ps1);
int end = ps1->size - 1;
while (end >= 0)
{
ps1->a[end + 1] = ps1->a[end];
end--;
}
ps1->a[0] = x;
ps1->size++;
}
void SeqListPopBack(SLT* ps1)//尾删
{
assert(ps1);
assert(ps1->size > 0);
//ps1->a[ps1->size - 1] = 0;没必要,直接删除
ps1->size--;
}
void SeqListPopFront(SLT* ps1)//头删
{
assert(ps1);
assert(ps1->size > 0);
int begin = 1;
while (begin < ps1->size)
{
ps1->a[begin - 1] = ps1->a[begin];
begin++;
}
if (ps1->size > 0)
{
ps1->size--;
}
}
小结:
1.空间不够增容
2.插入跟删除都得要求数据要连续
下面继续接着实现3个接口:
查找:
int SeqListFind(SLT* ps1, SQDataType x)//查找
{
assert(ps1);
for (int i = 0; i < ps1->size; i++)
{
if (ps1->a[i] == x)
{
return i;
}
}
return -1;
}
在中间插入某个数(重要!):
注意有符号和无符号
void SeqListInsert(SLT* ps1, size_t pos, SQDataType x)
{
assert(ps1);
assert(pos <= ps1->size && pos>=0);
SeqListCheckCapacity(ps1);
//假如pos=0或者end=0,会发生整型提升
//方案1:将pos强制类型转换成int
/*int end = ps1->size - 1;
while (end >= (int)pos)
{
ps1->a[end + 1] = ps1->a[end];
end--;
}*/
//方案2(推荐):用size_t要防止这个数变成-1
size_t end = ps1->size;
while (end > pos)
{
ps1->a[end] = ps1->a[end-1];//防止了end变为-1
end--;
}
ps1->a[pos] = x;
ps1->size++;
}
总结:要避免负数给到无符号,或者避免有符号数变成负数以后,被提升或者强转成有符号
删除某个数:
void SeqListErase(SLT* ps1, size_t pos)
{
assert(ps1);
assert(pos < ps1->size);
size_t begin = pos;
while (begin < ps1->size - 1)
{
ps1->a[begin] = ps1->a[begin+1];
begin++;
}
ps1->size--;
}
菜单:
void menu()
{
printf("***********************************\\n");
printf(" 1.尾插数据 2.头插数据 \\n");
printf(" 3.尾删数据 4.头删数据 \\n");
printf(" 5. 打印 0. 退出 \\n");
printf("***********************************\\n");
}
int main()
{
int input = 0;
SLT s;
SeqListInit(&s);
int val = 0;
int front = 0;
do
{
menu();
printf("请选择操作选项:>");
scanf("%d", &input);
switch (input)
{
case 0:
break;
case 1:
printf("请输入要尾插数据,以-1结束:");
scanf("%d",&val);
while (val != -1)
{
SeqListPushBack(&s, val);
scanf("%d", &val);
}
break;
case 2:
printf("请输入要头插数据,以-1结束:");
scanf("%d",&front);
while (front != -1)
{
SeqListPushFront(&s, front);
scanf("%d",&front);
}
break;
case 3:
SeqListPopBack(&s);
break;
case 4:
SeqListPopFront(&s);
break;
case 5:
SeqListPrint(&s);
break;
default:
printf("无此选项,请重新输入");
break;
}
}while (input != 0);
SeqListDestory(&s);
//TestSeqList();
//越界不一定报错,系统对越界的检查是一种抽查
//访问修改数据结构的建议一定用函数去,这样是最安全靠谱的
return 0;
}
完整代码:顺序表
以上是关于数据结构顺序表——链表的主要内容,如果未能解决你的问题,请参考以下文章