一、概念
1.1 线性表
线性表 (linear list)是n个具有相同特性的数据元素的有限序列。
常见的线性表:顺序表、链表、栈、队列、字符串等
线性表在逻辑上是一条直线,物理结构上以数组或者链表形式存储
1.2 顺序表
地址连续的存储单元顺序存储线性表中的各个数据元素,逻辑上相邻的数据元素在物理位置上也相邻。( 用一段地址连续的存储单元依次存储线性表的数据元素 )。
顺序表分为两种
- 静态顺序表:使用定长数组存储。
- 动态顺序表:使用动态开辟的数组存储,容量不受限制,支持数据插入,删除,修改等一系列操作。
二、顺序表的实现
2.1 静态顺序表(数组)
略
2.2 动态顺序表实现
2.2.1 定义数据类型
typedef int datatype;
typedef struct
{
datatype *Head; //声明了一个名为Head的长度不确定的数组,也叫“动态数组”
int ListLength; //记录当前顺序表的长度
int ListSize; //记录顺序表分配的存储容量
}SqList;
2.2.2 初始化
SqList InitTable(int Size) //初始化顺序表
{
SqList TableList;
TableList.Head == NULL;
if (Size < 0) {
printf ("size is out of range!\n");
}
TableList.Head=(int*)malloc(Size * sizeof(datatype));
if (TableList.Head == NULL) {
printf ("Init table fail !!!\n");
//return ;
}
TableList.ListLength = Size;
TableList.ListSize = 0;
printf ("Init table is successful !!!\n");
return TableList;
}
2.2.3 打印
void SqListPrint (SqList* Sq) //打印顺序表
{
if (Sq == NULL) {
printf ("sqListPrint not table!!!\n");
return ;
}
for(int i = 0; i < Sq->ListSize; i++) {
printf ("%d -> ",Sq->Head[i]);
}
printf ("\n");
}
2.2.4 扩大存储空间
int CheckSqList (SqList* Sq) //检查数据空间是否填满,填满就扩大存储空间
{
datatype *data_tmp = NULL;
if (Sq == NULL) {
printf ("CheckSqList not table!!!\n");
return -1;
}
if (Sq->ListLength <= Sq->ListSize) { //判断数据是否存满,如果存满存储空间扩大一倍
printf ("sqlist space is full, realloc new space!!!\n");
data_tmp = realloc (Sq->Head, sizeof (datatype) * Sq->ListLength * 2);
if (data_tmp == NULL) {
printf ("checkSqlist realloc is error! line : %d",__LINE__);
return -1;
}
Sq->Head = data_tmp;
Sq->ListLength = Sq->ListLength * 2;
}
return 0;
}
2.2.5 尾插
int InsertSqTail (SqList* Sq, datatype data) //尾插
{
if (CheckSqList (Sq)) { //检查存储空间是否够用
printf ("InsertSqTail CheckSqList is error !!!\n");
return -1;
}
Sq->Head[Sq->ListSize] = data;
Sq->ListSize++;
return 0;
}
2.2.6 头插
int InsertSqHead (SqList* Sq, datatype data) //头插
{
if (CheckSqList (Sq)) { //检查存储空间是否够用
printf ("InsertSqHead CheckSqList is error !!!\n");
return -1;
}
for (int i = 0; i < Sq->ListSize; i++) {
Sq->Head[Sq->ListSize - i] = Sq->Head[Sq->ListSize - i - 1];
}
Sq->Head[0] = data;
Sq->ListSize++;
return 0;
}
2.2.7 选择插
int InsertSq (SqList* Sq, int num, datatype data) //选择插 num是插入在第几个位置
{
if (CheckSqList (Sq)) { //检查存储空间是否够用
printf ("InsertSq CheckSqList is error !!!\n");
return -1;
}
if (num > Sq->ListSize || num < 0) {
printf ("num is large !!! \n");
return -1;
}
for (int i = 0; i <= Sq->ListSize - num; i++) {
Sq->Head[Sq->ListSize - i] = Sq->Head[Sq->ListSize - i - 1];
}
Sq->Head[num - 1] = data;
Sq->ListSize++;
return 0;
}
2.2.8 尾删
int DeleteSqTail (SqList* Sq) //尾删
{
if (Sq == NULL) {
printf ("DeleteSqTail not table !!!\n");
return -1;
}
if (Sq->ListSize) {
printf ("table is null data !!! \n");
return -1;
}
Sq->Head[Sq->ListSize -1] = 0;
Sq->ListSize--;
return 0;
}
2.2.9 头删
int DeleteSqHead (SqList* Sq) //头删
{
if (Sq == NULL) {
printf ("DeleteSqHead not table !!!\n");
return -1;
}
if (Sq->ListSize) {
printf ("table is null data !!! \n");
return -1;
}
for (int i = 1; i < Sq->ListSize; i++) {
Sq->Head[i-1] = Sq->Head[i];
}
Sq->ListSize--;
return 0;
}
2.2.10 选择删除
int DeleteSq (SqList* Sq, int num) //选择删, num 是第几个
{
if (Sq == NULL) {
printf ("DeleteSqHead not table !!!\n");
return -1;
}
if (Sq->ListSize) {
printf ("table is null data !!! \n");
return -1;
}
for (int i = 1; i < Sq->ListSize - num; i++) {
Sq->Head[num + i - 2] = Sq->Head[num + i - 1];
}
Sq->ListSize--;
return 0;
}
2.2.11 寻找元素存在位置
int FindSqData (SqList* Sq, datatype ElemData) //寻找输入元素存在位置
{
if (Sq == NULL) {
printf ("FindSqData not table !!!\n");
return -1;
}
for (int i = 0; i < Sq->ListSize; i++) {
if (Sq->Head[i] == ElemData) {
printf ("find data in : %d",i);
return i;
}
}
return 0;
}
2.2.12 返回当前长度
int FindSqListSize (SqList* Sq) //返回当前长度
{
if (Sq == NULL) {
printf ("FindSqSize not table !!!\n");
return -1;
}
return Sq->ListSize;
}
2.2.13 排序
#define ORDER 1
#define RE_ORDER 2
int OderSortSq (SqList* Sq , int Flag) //排序---冒泡排序
{
if (Sq == NULL) {
printf ("ChangeSqData not table !!!\n");
return -1;
}
switch (Flag)
{
case ORDER:
for (int i = 0; i < Sq->ListSize -1; i++) {
for (int j = 0; j < Sq->ListSize - i - 1; j++) {
if (Sq->Head[j] > Sq->Head[j+1]) {
Sq->Head[j] = Sq->Head[j] + Sq->Head[j+1];
Sq->Head[j+1] = Sq->Head[j] - Sq->Head[j+1];
Sq->Head[j] = Sq->Head[j] - Sq->Head[j+1];
}
}
}
break;
case RE_ORDER:
for (int i = 0; i < Sq->ListSize -1; i++) {
for (int j = 0; j < Sq->ListSize - i - 1; j++) {
if (Sq->Head[j] < Sq->Head[j+1]) {
Sq->Head[j] = Sq->Head[j] + Sq->Head[j+1];
Sq->Head[j+1] = Sq->Head[j] - Sq->Head[j+1];
Sq->Head[j] = Sq->Head[j] - Sq->Head[j+1];
}
}
}
break;
default:
printf ("Flag is error!\n");
return -1;
}
return 0;
}
2.2.14 修改相应数据
int ChangeSqData (SqList* Sq, int num, datatype data) //修改
{
if (Sq == NULL) {
printf ("ChangeSqData not table !!!\n");
return -1;
}
Sq->Head[num-1] = data;
return 0;
}
2.2.15 翻转
int ReversalSq (SqList *Sq) //翻转顺序表
{
int i;
// 第一个与最后一个互换 第二个与倒数第二个互换 ......
//最后实现全部数据翻转
for (i = 0; i <= (Sq->ListSize - 1)/2; i++) {
datatype datatmp = Sq->Head[i];
Sq->Head[i] = Sq->Head[Sq->ListLength - 1 - i];
Sq->Head[Sq->ListLength - 1 - i] = datatmp;
}
return 0;
}
2.2.16 销毁顺序表
int DestroySq (SqList* Sq) //销毁
{
if (Sq == NULL) {
printf ("ChangeSqData not table !!!\n");
return -1;
}
free (Sq->Head);
Sq->Head = NULL;
Sq->ListLength = 0;
Sq->ListSize = 0;
return 0;
}
2.3 测试
int main(void)
{
SqList sqlist;
sqlist = InitTable (INITSIZE);
InsertSqTail (&sqlist, 4);
InsertSqTail (&sqlist, 5);
InsertSqTail (&sqlist, 2);
InsertSqHead (&sqlist, 1);
InsertSqHead (&sqlist, 3);
printf("size : %d\n",FindSqListSize (&sqlist));
SqListPrint (&sqlist);
InsertSqTail (&sqlist , 9);
InsertSqTail (&sqlist , 8);
InsertSqTail (&sqlist , 6);
InsertSq (&sqlist , 6, 7);
InsertSq (&sqlist , 7, 10);
printf("size : %d\n",FindSqListSize (&sqlist));
SqListPrint (&sqlist);
printf ("please start order: \n");
OderSortSq (&sqlist, ORDER);
SqListPrint (&sqlist);
printf ("please start Reverse order: \n");
OderSortSq (&sqlist, RE_ORDER);
SqListPrint (&sqlist);
printf ("please start change:\n");
ChangeSqData (&sqlist, 1, 11);
ChangeSqData (&sqlist, 2, 12);
ChangeSqData (&sqlist, 3, 13);
SqListPrint (&sqlist);
printf ("begin reversal data!\n");
ReversalSq (&sqlist);
SqListPrint (&sqlist);
DestroySq (&sqlist);
return 0;
}