顺序表
同数组一样,一段连续的空间,地址由低到高
分为静态顺序表和动态顺序表
静态顺序表
typedef int DataType;
struct SeqList
{
DataType _arr[100]; //顺序表的空间大小
int _size; //当前空间有效数据的大小
};
动态顺序表
typedef int DataType;
struct SeqList
{
DataType *_a; //数据块的指针
size_t capicity; //数据块的容量
size_t size; //当前空间有效数据的大小
}
二者区别
静态顺序表只能开辟有限个空间,即容量是固定的
动态顺序表可增加容量,即容量可任意添加
具体实现
1. 头插与尾插
1)头插
指在顺序表的头添加数据,所添加的顺序表是倒序输出(如下图)
代码实现:
//头插
void SeqPushFront(SeqList* pSeq, DataType x)
{
assert(pSeq);
SeqList* SeqList;
SeqList = IsFULL(pSeq);
if (SeqList != NULL)
{
int begin = pSeq->_size-1;
while (begin >= 0)
{
pSeq->_a[begin + 1] = pSeq->_a[begin];
--begin;
}
pSeq->_a[0] = x;
++pSeq->_size;
}
}
2)尾插
指在循序表的尾部插入数据,即插入的数据是正序输出(如下图)
代码实现:
//尾插
void SeqPushBack(SeqList* pSeq, DataType x)
{
assert(pSeq);
SeqList *SeqList;
SeqList = IsFULL(pSeq);
/*if (SeqList != NULL)
{
size_t begin = 0;
while (begin < pSeq->_size)
{
++begin;
}
pSeq->_a[begin] = x;
pSeq->_size++;
}*/
SeqInsert(pSeq, pSeq->_size, x);
}
2.头删与尾删
1)头删
将后面位置的数据向前移动,并减少有效数据个数
当顺序表的有效个数为0,即顺序表为空,不能再删除
代码:
//头删
void SeqPopFront(SeqList* pSeq)
{
assert(pSeq);
if (pSeq->_size == 0)
{
printf("List is empty\n");
}
size_t begin = 0;
while (begin < pSeq->_size)
{
pSeq->_a[begin + 1] = pSeq->_a[begin];
--pSeq->_size;
}
}
2)尾删
因为是在尾部删除,即只需将顺序表的有效个数减1即可
同样需判断是否为0的情况
具体代码:
//尾删
void SeqPopBack(SeqList* pSeq)
{
assert(pSeq);
if (pSeq->_size == 0)
{
printf("List is empty\n");
}
int i = pSeq->_size - 1;
while (i >= 0)
{
--i;
--pSeq->_size;
}
}
3.任意位置的插入与删除
1)插入
前面讲过头插,只在顺序表的最前面插入数据,将其所有数据向后移动;任意位置 插入,即只需将任意位置(pos)位置以后的数据向后移动,将其插入在pos位置(如图)
代码:
//任意位置插入
void SeqInsert(SeqList* pSeq, size_t pos, DataType x)
{
assert(pSeq);
assert(pos <= pSeq->_size);
SeqList *SeqList;
SeqList = IsFULL(pSeq);
if (SeqList)
{
int begin = pos;
int end = pSeq->_size - 1;
while (end >= (int)pos)
{
pSeq->_a[end + 1] = pSeq->_a[end];
--end;
}
pSeq->_a[pos] = x;
++pSeq->_size;
}
}
2)删除
前面讲过头删,将所有数据向前移动,并将有效数据个数减 1,任意位置删除,即将pos位置后的数据向前移动一个数据,并将有效个数减1(如图)
代码:
//任意位置删除
void SeqErase(SeqList* pSeq, size_t pos)
{
assert(pSeq);
assert(pos <= pSeq->_size);
if (pSeq->_size == 0)
{
printf("List is empty\n");
}
size_t end = pos;
while (end < pSeq->_size)
{
pSeq->_a[end] = pSeq->_a[end+1];
++end;
}
--pSeq->_size;
}
4.查找
1)二分查找
代码:
//二分查找
int BinarySearch(SeqList* pSeq,DataType x)
{
assert(pSeq);
size_t begin = 0;
size_t end = pSeq->_size - 1;
while (begin <= end)
{
size_t mid = begin + ((end - begin) >> 1);
if (pSeq->_a[mid]==x)
{
return mid;
}
else if (pSeq->_a[mid] > x )
{
end = mid - 1;
}
else
begin = mid + 1;
}
return -1;
}
5.排序
1)冒泡排序(这里不深究)
代码:
//冒泡排序
void swap(DataType *x, DataType *y)
{
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
void BubbleSort(SeqList* pSeq)
{
assert(pSeq);
size_t begin = 0;
size_t end = pSeq->_size - 1;
while (begin < end)
{
size_t flag = 0;
for (size_t i = 0; i < end; i++)
{
if (pSeq->_a[i]>pSeq->_a[i + 1])
{
flag = 1;
swap(&pSeq->_a[i], &pSeq->_a[i + 1]);
}
}
if (flag == 0)
{
return;
}
++begin;
--begin;
}
}
2)选择排序
类似于冒泡排序,每次遍历顺序表选出最小值与最大值,分别放在最左边和最右边(一次排序过程如下图)
代码:
//选择排序
void Swap(DataType *x, DataType *y)
{
DataType tmp = *x;
*x = *y;
*y = tmp;
}
void SelectSort(SeqList* pSeq)
{
assert(pSeq);
size_t begin = 0;
size_t end = pSeq->_size - 1;
while (begin < end)
{
size_t max = begin;
size_t min = begin;
size_t i = begin;
while (i <= end)
{
if (pSeq->_a[i] < pSeq->_a[min])
{
min = i;
}
if (pSeq->_a[i]>pSeq->_a[max])
{
max = i;
}
++i;
}
Swap(&pSeq->_a[begin], &pSeq->_a[min]);
if (max == begin)
{
max = min;
}
Swap(&pSeq->_a[end], &pSeq->_a[max]);
++begin;
--end;
}
}
下面给出所有代码及其测试代码:
SeqList.h
#ifndef __SeqList_H__
#define __SeqList_H__
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#define MAX 3;
typedef int DataType;
typedef struct SeqList
{
DataType *_a;
size_t _size;
size_t _capicity;
}SeqList;
void SeqPrint(SeqList* pSeq);//打印
void SeqInit(SeqList* pSeq); //初始化
void SeqDestory(SeqList* pSeq);//释放
void SeqPushBack(SeqList* pSeq, DataType x);//尾插
void SeqPopBack(SeqList* pSeq);//尾删
void SeqPushFront(SeqList* pSeq, DataType x);//头插
void SeqPopFront(SeqList* pSeq);//头删
void SeqInsert(SeqList* pSeq, size_t pos, DataType x);//任意位置插入
void SeqErase(SeqList* pSeq, size_t pos);//任意位置删除
int SeqFind(SeqList* pSeq, DataType x);//查找
void SeqAt(SeqList* pSeq, size_t pos, DataType x);//修改
int BinarySearch(SeqList* pSeq,DataType x);//二分查找
void BubbleSort(SeqList* pSeq);//冒泡排序
void SelectSort(SeqList* pSeq);//选择排序
void TsetSeqPushBack();//测试尾插
void TsetSeqPopBack();//测试尾删
void TestSeqPushFront();//测试头插
void TestSeqPopFront();//测试头删
void TestSeqInsert();//测试任意位置插入
void TestSeqErase();//测试任意位置删除
void TestSeqFind();//测试查找
void TestSeqAt();//测试修改
void TestBubbleSort();//测试冒泡排序
void TestSelectSort();//测试选择排序
#endif //__SeqList_H__
SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
SeqList list;
//初始化
void SeqInit(SeqList* pSeq)
{
pSeq->_capicity = MAX;
pSeq->_a = (DataType *)malloc(sizeof(DataType)*pSeq->_capicity);
pSeq->_size = 0;
memset(pSeq->_a,0,sizeof(DataType));
}
//释放
void SeqDestory(SeqList* pSeq)
{
free(pSeq->_a);
pSeq->_capicity = 0;
}
//打印
void SeqPrint(SeqList* pSeq)
{
assert(pSeq);
size_t i = 0;
for (i = 0; i < pSeq->_size; i++)
{
printf("%3d", pSeq->_a[i]);
}
printf("\n");
}
//判满
SeqList *IsFULL(SeqList *pSeq)
{
assert(pSeq);
if (pSeq->_capicity == pSeq->_size)
{
pSeq->_a = (DataType *)realloc(pSeq->_a, sizeof(DataType)*pSeq->_capicity * 2);
pSeq->_capicity = pSeq->_capicity * 2;
}
return pSeq;
}
//尾插
void SeqPushBack(SeqList* pSeq, DataType x)
{
assert(pSeq);
SeqList *SeqList;
SeqList = IsFULL(pSeq);
/*if (SeqList != NULL)
{
size_t begin = 0;
while (begin < pSeq->_size)
{
++begin;
}
pSeq->_a[begin] = x;
pSeq->_size++;
}*/
SeqInsert(pSeq, pSeq->_size, x);
}
//尾删
void SeqPopBack(SeqList* pSeq)
{
assert(pSeq);
if (pSeq->_size == 0)
{
printf("List is empty\n");
}
int i = pSeq->_size - 1;
while (i >= 0)
{
--i;
--pSeq->_size;
}
}
//头插
void SeqPushFront(SeqList* pSeq, DataType x)
{
assert(pSeq);
SeqList* SeqList;
SeqList = IsFULL(pSeq);
/*if (SeqList != NULL)
{
int begin = pSeq->_size-1;
while (begin >= 0)
{
pSeq->_a[begin + 1] = pSeq->_a[begin];
--begin;
}
pSeq->_a[0] = x;
++pSeq->_size;
}*/
SeqInsert(pSeq, 0, x);
}
//头删
void SeqPopFront(SeqList* pSeq)
{
assert(pSeq);
if (pSeq->_size == 0)
{
printf("List is empty\n");
}
size_t begin = 0;
while (begin < pSeq->_size)
{
pSeq->_a[begin + 1] = pSeq->_a[begin];
--pSeq->_size;
}
}
//任意位置插入
void SeqInsert(SeqList* pSeq, size_t pos, DataType x)
{
assert(pSeq);
assert(pos <= pSeq->_size);
SeqList *SeqList;
SeqList = IsFULL(pSeq);
if (SeqList)
{
int begin = pos;
int end = pSeq->_size - 1;
while (end >= (int)pos)
{
pSeq->_a[end + 1] = pSeq->_a[end];
--end;
}
pSeq->_a[pos] = x;
++pSeq->_size;
}
}
//任意位置删除
void SeqErase(SeqList* pSeq, size_t pos)
{
assert(pSeq);
assert(pos <= pSeq->_size);
if (pSeq->_size == 0)
{
printf("List is empty\n");
}
size_t end = pos;
while (end < pSeq->_size)
{
pSeq->_a[end] = pSeq->_a[end+1];
++end;
}
--pSeq->_size;
}
//查找
int SeqFind(SeqList* pSeq, DataType x)
{
assert(pSeq);
size_t begin = 0;
while (begin < pSeq->_size)
{
if (pSeq->_a[begin] == x)
{
return begin;
}
++begin;
}
return -1;
}
//二分查找
int BinarySearch(SeqList* pSeq,DataType x)
{
assert(pSeq);
size_t begin = 0;
size_t end = pSeq->_size - 1;
while (begin <= end)
{
size_t mid = begin + ((end - begin) >> 1);
if (pSeq->_a[mid]==x)
{
return mid;
}
else if (pSeq->_a[mid] > x )
{
end = mid - 1;
}
else
begin = mid + 1;
}
return -1;
}
//修改
void SeqAt(SeqList* pSeq, size_t pos, DataType x)
{
assert(pSeq);
assert(pos < pSeq->_size);
size_t begin = 0;
while (begin <= pos)
{
++begin;
}
pSeq->_a[pos] = x;
}
//冒泡排序
void swap(DataType *x, DataType *y)
{
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
void BubbleSort(SeqList* pSeq)
{
assert(pSeq);
size_t begin = 0;
size_t end = pSeq->_size - 1;
while (begin < end)
{
size_t flag = 0;
for (size_t i = 0; i < end; i++)
{
if (pSeq->_a[i]>pSeq->_a[i + 1])
{
flag = 1;
swap(&pSeq->_a[i], &pSeq->_a[i + 1]);
}
}
if (flag == 0)
{
return;
}
++begin;
--begin;
}
}
//选择排序
void Swap(DataType *x, DataType *y)
{
DataType tmp = *x;
*x = *y;
*y = tmp;
}
void SelectSort(SeqList* pSeq)
{
assert(pSeq);
size_t begin = 0;
size_t end = pSeq->_size - 1;
while (begin < end)
{
size_t max = begin;
size_t min = begin;
size_t i = begin;
while (i <= end)
{
if (pSeq->_a[i] < pSeq->_a[min])
{
min = i;
}
if (pSeq->_a[i]>pSeq->_a[max])
{
max = i;
}
++i;
}
Swap(&pSeq->_a[begin], &pSeq->_a[min]);
if (max == begin)
{
max = min;
}
Swap(&pSeq->_a[end], &pSeq->_a[max]);
++begin;
--end;
}
}
测试用例:
test.c
//测试尾插
void TsetSeqPushBack()
{
SeqInit(&list);
SeqPushBack(&list, 0);
SeqPushBack(&list, 1);
SeqPushBack(&list, 2);
SeqPushBack(&list, 3);
SeqPushBack(&list, 4);
SeqPushBack(&list, 5);
SeqPushBack(&list, 6);
SeqPushBack(&list, 7);
SeqPrint(&list);
}
//测试尾删
void TsetSeqPopBack()
{
SeqInit(&list);
SeqPushBack(&list, 0);
SeqPushBack(&list, 1);
SeqPushBack(&list, 2);
SeqPushBack(&list, 3);
SeqPushBack(&list, 4);
SeqPushBack(&list, 5);
SeqPushBack(&list, 6);
SeqPushBack(&list, 7);
SeqPrint(&list);
SeqPopBack(&list);
SeqPrint(&list);
}
//测试头插
void TestSeqPushFront()
{
SeqInit(&list);
SeqPushBack(&list, 0);
SeqPushBack(&list, 1);
SeqPushBack(&list, 2);
SeqPushBack(&list, 3);
SeqPrint(&list);
SeqPushFront(&list, 5);
SeqPushFront(&list, 6);
SeqPushFront(&list, 7);
SeqPushFront(&list, 8);
SeqPushFront(&list, 9);
SeqPrint(&list);
}
//测试头删
void TestSeqPopFront()
{
SeqInit(&list);
SeqPushBack(&list, 0);
SeqPushBack(&list, 1);
SeqPushBack(&list, 2);
SeqPushBack(&list, 3);
SeqPushFront(&list, 5);
SeqPushFront(&list, 6);
SeqPushFront(&list, 7);
SeqPushFront(&list, 8);
SeqPushFront(&list, 9);
SeqPrint(&list);
SeqPopFront(&list);
SeqPrint(&list);
SeqPrint(&list);
}
//测试任意位置插入
void TestSeqInsert()
{
SeqInit(&list);
SeqPushBack(&list, 0);
SeqPushBack(&list, 1);
SeqPushBack(&list, 2);
SeqPushBack(&list, 3);
SeqPrint(&list);
SeqInsert(&list, 3, 5);
SeqInsert(&list, 2, 6);
SeqInsert(&list, 0, 7);
SeqPrint(&list);
}
//测试任意位置删除
void TestSeqErase(SeqList* pSeq, size_t pos)
{
SeqInit(&list);
SeqPushBack(&list, 0);
SeqPushBack(&list, 1);
SeqPushBack(&list, 2);
SeqPushBack(&list, 3);
SeqInsert(&list, 3, 5);
SeqInsert(&list, 2, 6);
SeqInsert(&list, 0, 7);
SeqPrint(&list);
SeqErase(&list, 0);
SeqErase(&list, 3);
SeqErase(&list, 5);
SeqPrint(&list);
}
//测试查找
void TestSeqFind()
{
SeqInit(&list);
SeqPushBack(&list, 0);
SeqPushBack(&list, 1);
SeqPushBack(&list, 2);
SeqPushBack(&list, 3);
SeqInsert(&list, 4, 5);
SeqInsert(&list, 5, 6);
SeqInsert(&list, 6, 7);
SeqPrint(&list);
/*printf("%d\n", SeqFind(&list, 0));
printf("%d\n", SeqFind(&list, 1));
printf("%d\n", SeqFind(&list, 2));
printf("%d\n", SeqFind(&list, 3));
printf("%d\n", SeqFind(&list, 4));
printf("%d\n", SeqFind(&list, 5));
printf("%d\n", SeqFind(&list, 6));
printf("%d\n", SeqFind(&list, 7));*/
printf("%d\n", BinarySearch(&list, 0));
printf("%d\n", BinarySearch(&list, 1));
printf("%d\n", BinarySearch(&list, 2));
printf("%d\n", BinarySearch(&list, 3));
printf("%d\n", BinarySearch(&list, 4));
printf("%d\n", BinarySearch(&list, 5));
printf("%d\n", BinarySearch(&list, 6));
printf("%d\n", BinarySearch(&list, 7));
}
//测试修改
void TestSeqAt()
{
SeqInit(&list);
SeqPushBack(&list, 0);
SeqPushBack(&list, 1);
SeqPushBack(&list, 2);
SeqPushBack(&list, 3);
SeqInsert(&list, 4, 5);
SeqInsert(&list, 5, 6);
SeqInsert(&list, 6, 7);
SeqPrint(&list);
SeqAt(&list, 1, 89);
SeqAt(&list, 3, 23);
SeqAt(&list, 5, 67);
SeqPrint(&list);
}
//测试冒泡排序
void TestBubbleSort()
{
SeqInit(&list);
SeqPushBack(&list, 1);
SeqPushBack(&list, 0);
SeqPushBack(&list, 67);
SeqPushBack(&list, 23);
SeqPushBack(&list, -1);
SeqPushBack(&list, 5);
SeqPushBack(&list, 3);
SeqPrint(&list);
BubbleSort(&list);
SeqPrint(&list);
}
//测试选择排序
void TestSelectSort()
{
SeqInit(&list);
SeqPushBack(&list, 7);
SeqPushBack(&list, 5);
SeqPushBack(&list, 78);
SeqPushBack(&list, 9 );
SeqPushBack(&list, -1);
SeqPushBack(&list, 45);
SeqPushBack(&list, 4);
SeqPrint(&list);
SelectSort(&list);
SeqPrint(&list);
}