顺序表:
采用顺序存储结构存储的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表在逻辑结构上相邻的元素存储在连续的物理存储单元中。即通过数据元素物理存储的连续性来反映元素之间逻辑上的相邻关系。
以下我用了三个源文件来实现顺序表:
SeqList.h //头文件&函数声明
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#pragma once
typedef int SLDataType;
// 顺序表的动态存储
typedef struct SeqList
{
SLDataType* _array; // 指向动态开辟的数组
size_t _size; // 有效数据个数
size_t _capacity; // 容量空间的大小
}SeqList;
void SeqListInit(SeqList* psl, size_t capacity); //初始化:定义一个空顺序表
void SeqListDestory(SeqList* psl); // 销毁:释放所有值
void CheckCapacity(SeqList* psl); // 检查容量:若不足则扩容,数组直接追加
void SeqListPushBack(SeqList* psl, SLDataType x); //尾插:要记得检查容量,直接插入,数据个数改变
void SeqListPopBack(SeqList* psl); //尾删;可用_size控制,直接操作,数据个数改变
void SeqListPushFront(SeqList* psl, SLDataType x); //头插:记得检查容量,且将所有值后移再插入第一个位置,数据个数改变
void SeqListPopFront(SeqList* psl); //头删:从第二个数开始,依次前移,数据个数改变
//SLDataType SeqListFind(SeqList* psl, SLDataType x); //查找元素,返回下标
int SeqListFind(SeqList* psl, SLDataType x); //找顺序表中的某个值:找到了返回1,否则返回0
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x); //在指定位置插入:将指定位置及之后的值都向后移,再插入x,数据个数改变
void SeqListErase(SeqList* psl, size_t pos); //删除指定位置:将指定位置之后的值依次向前移,数据个数改变
void SeqListRemove(SeqList* psl, SLDataType x); //删除指定值:找到x,将其后的值依次向前覆盖
void SeqListModify(SeqList* psl, size_t pos, SLDataType x); //修改指定位置的值:直接将指定位置的值用x覆盖
void SeqListPrint(SeqList* psl); //打印顺序表:按数组打印
void SeqListTest1(); //测试类
// 扩展面试题实现
void SeqListBubbleSort(SeqList* psl);
//顺序表排序:用冒泡排序,即比较相邻的两个值,判断是否交换
int SeqListBinaryFind(SeqList* psl, SLDataType x);
//二分查找:找到返回,否则返回0
// 本题要求:时间复杂度:O(N) 空间复杂度 O(1)
void SeqListRemoveAll(SeqList* psl, SLDataType x);
//删除所有x,重复做删除指定值的操作
int SeqListEmpty(SeqList* psl);
//判断是否为空:空为0,否则返回1
SeqList.c // 基本增删查改接口函数实现
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
void SeqListInit(SeqList* psl, size_t capacity) //初始化:开辟空间且有效个数为0
{
assert(psl);
psl->_array = (SLDataType*)malloc(sizeof(SLDataType)*capacity);
psl->_size = 0;
psl->_capacity = capacity;
}
void SeqListDestory(SeqList* psl) //销毁:释放数据
{
assert(psl);
if (psl->_array)
{
free(psl->_array );
psl->_array = NULL;
psl->_capacity = psl->_size = 0;
}
printf("已销毁!\n");
}
void CheckCapacity(SeqList* psl) //检查容量:不够就2倍增容
{
assert(psl);
if (psl->_size == psl ->_capacity)
{
psl->_capacity *= 2;
psl->_array = realloc(psl->_array, psl->_capacity*sizeof(SLDataType)); //需要传字节数
assert(psl->_array);
}
}
void SeqListPushBack(SeqList* psl, SLDataType x) //尾插
{
assert(psl);
CheckCapacity(psl); //检查容量
psl->_array[psl->_size++] = x; //_size位置插入,_size再加1
// psl->_size++; SeqListInsert(psl,psl->_size,x); //insert表示在第pos的位置插入
}
void SeqListPopBack(SeqList* psl) //尾删:直接size减一
{
assert(psl&&psl->_size>0);
//psl->_array[psl->_size - 1] = 0; //将最后一个元素变为0(可不操作)
psl->_size--;
}
void SeqListPushFront(SeqList* psl, SLDataType x) //头插
{
assert(psl);
CheckCapacity(psl);
int end = psl->_size - 1; //若用size_t(无符号)定义end,则它永远不可能<0,循环无法停止
while (end>=0)
{
psl->_array[end + 1] = psl->_array[end]; //从最后一个元素开始,依次向后挪元素
end--;
}
psl->_array[0] = x; //第一个元素赋值
psl->_size++;
}
void SeqListPopFront(SeqList* psl) //头删
{
assert(psl);
CheckCapacity(psl);
size_t begain = 0;
while (begain< psl->_size-1)
{
psl->_array[begain] = psl->_array[begain + 1]; //从第二个元素开始,一次向前覆盖元素
begain++;
}
psl->_size--; //size减一
}
//SLDataType SeqListFind(SeqList* psl, SLDataType x) //查找元素,返回下标
//{
// assert(psl);
// for (size_t i = 0; i < psl->_size ;i++)
// {
// if (psl->_array[i] == x)
// {
// return i; } }
// return -1;
//}
int SeqListFind(SeqList* psl, SLDataType x) //查找元素,返回是否查到
{
assert(psl);
for (size_t i = 0; i < psl->_size; i++)
{
if (psl->_array[i] == x)
{
return 1; } }
return 0;
}
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x) //指定位置插入
{
assert(psl&&pos<=psl->_size);
CheckCapacity(psl);
int end = psl->_size-1;
while (end>=(int)pos) //向后挪size-pos+1个元素
{
psl->_array[end+1] = psl->_array[end ];
end--;
}
psl->_array[pos] = x;
psl->_size++;
}
void SeqListErase(SeqList* psl, size_t pos) //指定位置删除
{
assert(psl&&pos <= psl->_size);
size_t begin = pos;
while (begin<psl->_size) //向前挪size-begin个元素
{
psl->_array[begin ] = psl->_array[begin+1];
begin++;
}
psl->_size--;
}
void SeqListRemove(SeqList* psl, SLDataType x) //删除指定的某个值:将x值用下一个值覆盖
{
assert(psl);
size_t cur = 0;
size_t dst = 0;
while (cur < psl->_size)
{
if (psl->_array[cur] != x)
{
psl->_array[dst] = psl->_array[cur]; //若不是x,则dst的值是cur的上一个
dst++;
}
cur++;
}
psl->_size = dst;
}
void SeqListModify(SeqList* psl, size_t pos, SLDataType x) // //修改指定位置的值:直接将指定位置的值用x覆盖
{
assert(psl&&pos<psl->_size);
psl->_array[pos] = x;
}
void SeqListPrint(SeqList* psl) //打印顺序表
{
assert(psl);
for (size_t i = 0; i < psl->_size; i++)
{
printf("%d ", psl->_array[i]);
}
printf("\n");
}
void SeqListTest1() //测试类
{
SeqList s1;
SLDataType find = 0;
SeqListInit(&s1, 10);
SeqListPushBack(&s1, 1);
SeqListPushBack(&s1, 2);
SeqListPushBack(&s1, 3);
SeqListPushBack(&s1, 4);
SeqListPushBack(&s1, 5);
SeqListPushBack(&s1, 6);
SeqListPushBack(&s1, 7);
SeqListPushBack(&s1, 8);
SeqListPushBack(&s1, 9);
SeqListPushBack(&s1, 9);
SeqListPushBack(&s1, 9);
printf("尾插的结果是:");
SeqListPrint(&s1);
SeqListPopBack(&s1);
printf("尾删的结果是:");
SeqListPrint(&s1);
SeqListPushFront(&s1, 0);
SeqListPushFront(&s1, 9);
printf("头插的结果是:");
SeqListPrint(&s1);
SeqListPopFront(&s1);
printf("头删的结果是:");
SeqListPrint(&s1);
/*printf("找%d 的结果是:",7);
find=SeqListFind(&s1, 7);
if (find< 0)
{
printf("找不到!\n");
}
else
{
printf("找到了!\n");
}*/
printf("找%d 的结果是:", 11);
int y=SeqListFind(&s1, 11);
if (y == 1)
printf("找到了!\n");
else printf("找不到! \n");
SeqListInsert(&s1, 4, 1);
printf("在下标为4位置插入1的结果是:");
SeqListPrint(&s1);
SeqListErase(&s1, 4);
printf("把下标为4位置删除的结果是:");
SeqListPrint(&s1);
SeqListRemove(&s1, 9);
printf("删除所有9的结果是:");
SeqListPrint(&s1);
SeqListModify(&s1, 4, 9);
printf("将第4个位置的值修改为9:");
SeqListPrint(&s1);
SeqListBubbleSort(&s1);
printf("排序后的结果为:");
SeqListPrint(&s1);
printf("二分查找5的结果:");
int s3 = SeqListBinaryFind(&s1, 5);
if (s3 == 1)
printf("找到了! \n");
else
printf("找不到! \n");
printf("二分查找11的结果:");
int s2 = SeqListBinaryFind(&s1, 11);
if (s2 == 1)
printf("找到了! \n");
else
printf("找不到! \n");
SeqListRemoveAll(&s1, 0);
printf("删除所有0的结果是:");
SeqListPrint(&s1);
int f=SeqListEmpty(&s1);
if (f == 0)
printf("顺序表已空! \n");
else
printf("顺序表未空! \n");
SeqListDestory(&s1);
}
void SeqListBubbleSort(SeqList* psl)
{
assert(psl);
size_t end = psl->_size - 1;
while (end)
{
int exchange = 0;
for (size_t i = 0; i < psl->_size-1; i++)
{
if (psl->_array[i]>psl->_array[i + 1])
{
SLDataType tmp = psl->_array[i];
psl->_array[i] = psl->_array[i + 1];
psl->_array[i + 1] = tmp;
exchange = 1;
}
}
if (exchange == 0)
break;
end--;
}
}
int SeqListBinaryFind(SeqList* psl, SLDataType x)
{
assert(psl);
size_t left = 0;
size_t right = psl->_size - 1;
while (left<=right)
{
size_t mid = (left + right) / 2;
if (psl->_array[mid] < x)
{
left = mid + 1;
}
else if (psl->_array[mid] > x)
{
right = mid-1;
}
else
{
return 1;
break;
}
}
return 0;
}
// 本题要求:时间复杂度:O(N) 空间复杂度 O(1)
void SeqListRemoveAll(SeqList* psl, SLDataType x)
{
assert(psl);
size_t i = 0;
while (i<psl->_size)
{
if (psl->_array[i] == x)
{
for (size_t j = i; j < psl->_size; j++)
{
psl->_array[j] = psl->_array[j + 1];
}
psl->_size--;
}
else
i++;
}
/*size_t cur = 0;
size_t dst = 0;
while (cur < psl->_size)
{
if (psl->_array[cur] != x)
{
psl->_array[dst] = psl->_array[cur];
dst++;
}
cur++;
}
psl->_size = dst;*/
}
int SeqListEmpty(SeqList* psl)
{
assert(psl);
if (psl->_size == 0)
{
return 0;
}
else
return 1;
}
Test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
int main()
{
SeqListTest1();
system("pause");
return 0;
}