1.线性结构
数据结构课程中数据的逻辑结构分为线性结构和非线性结构。
线性结构是一个有序数据元素的集合
常用的线性结构有:线性表,栈,队列,双队列,数组,串。
常见的非线性结构有:二维数组,多维数组,广义表,树(二叉树等)
2.线性结构中包含的内容
线性结构包含以下内容
(1)数据的逻辑结构。数据的逻辑结构与数据在计算机中的存储方式无关,它用来抽象地反映数据元素之间的逻辑关系。逻辑结构可分为线性结构和非线性结构。最常见的线性结构是线性表,最典型的非线性结构是树型结构。
(2)数据的存储结构。数据的存储结构实现了数据的逻辑结构在计算机内的存储问题,存储结构又称为物理结构。存储结构分为顺序存储结构与链式存储结构。
(3)数据的运算。数据的各种逻辑结构都有相对应的运算,每一种逻辑结构都有一个运算的集合。数据运算主要包括查找(检索)、排序、插入、更新及删除等。
3.顺序表
顺序表是用一种物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成增删改查等操作。
顺序表的分类:
(1)静态顺序表:使用定长数组存储
(2)动态顺序表:使用动态开辟的数组存储
4.顺序表程序
(1)创建
//动态顺序表
typedef int DataType;
typedef struct SeqList
{
DataType* _array;
int _capacity;//顺序表的总大小
int _size;//顺序表中有效元素的个数
}SeqList, * PSeq;
(2)初始化
void SeqListInit(PSeq ps, int capacity)
{
ps->_array = (DataType*)malloc(sizeof(DataType) * capacity);//申请空间
//malloc类型为void*,使用需要强制转换
if (NULL == ps->_array)//需要判空
{
assert(0);//仅调试时有用(debug版本)
return;
}
ps->_capacity = capacity;
ps->_size = 0;
}
(3)尾部插入一个数
void SeqListPushBack(PSeq ps, DataType data)//尾插
{
#if 0
assert(ps);
//顺序表满
CheckCapacity(ps);
ps->_array[ps->_size] = data;
ps->_size++;
#endif
SeqListInsert(ps, ps->_size, data);
}
(4)尾部删除一个数
void SeqListPopBack(PSeq ps)//尾删
{
#if 0
assert(ps);
if (SeqListEmpty(ps))
{
return;
}
ps->_size--;
#endif
SeqListErase(ps, ps->_size - 1);
}
(5)头部插入一个数
void SeqListPushFront(PSeq ps, DataType data)//头插
{
#if 0
assert(ps);
CheckCapacity(ps);
for (int i = ps->_size - 1; i > 0; i--)
{
ps->_array[i+1] = ps->_array[i];
}
ps->_array[0] = data;
ps->_size++;
#endif
SeqListInsert(ps, 0 ,data);
}
(6)头部删除一个数
void SeqListPopFront(PSeq ps)//头删
{
#if 0
if (SeqListEmpty(ps))
{
return;
}
for (int i = 1; i < ps->_size; ++i)
{
ps->_array[i-1]=ps->_array[i];
}
#endif
SeqListErase(ps, 0);
}
(7)顺序表判空
nt SeqListEmpty(PSeq ps)
{
assert(ps);
return 0 == ps->_size;
}
(8)任意位置插入一个数
void SeqListInsert(PSeq ps, int pos, DataType data)//任意位置插
{
assert(ps);
if (pos<0 || pos>ps->_size)
{
return;
}
CheckCapacity(ps);
for (int i = ps->_size - 1; i >= pos; i--)
{
ps->_array[i+1] = ps->_array[i];
}
ps->_array[pos] = data;
ps->_size++;
}
(9)任意位置删除一个数
void SeqListErase(PSeq ps, int pos)//任意位置删
{
assert(ps);
if (pos<0||pos>ps->_size)
{
return;
}
for (int i = pos+1; i <ps->_size ; ++i)
{
ps->_array[i-1] = ps->_array[i];
}
ps->_size--;
}
(10)查找一个数
int SeqListFind(PSeq ps, DataType data)//查找
{
assert(ps);
for (int i = 0; i < ps->_size; ++i)
{
if(ps->_array[i]==data)
{
return i;
}
}
return -1;
}
(11)顺序表中元素个数
int SeqListSize(PSeq ps)//元素个数
{
assert(ps);
return ps->_size;
}
(12)顺序表容量大小
int SeqListCapacity(PSeq ps)//容量大小
{
assert(ps);
return ps->_capacity;
}
(13)清空顺序表
void SeqListClear(PSeq ps)//清空
{
assert(ps);
ps->_size = 0;
}
(14)删除第一个值为data的元素
void SeqListRemove(PSeq ps, DataType data)//移除第一个值为data的元素
{
SeqListErase(ps, SeqListFind(ps, data));
}
(15)删除所有值为data的元素
void SeqListRemoveAll(PSeq ps, DataType data)//移除所有值为data的元素
{
assert(ps);
#if 0
int pos = -1;
while (-1!=(pos = SeqListFind(ps, data)))
{
SeqListErase(ps, pos);
}
#endif
int count=0;
for (int i = 0; i < ps->_size;++i)
{
if (data == ps->_array[i])
{
count++;
}
else
{
ps->_array[i - count] = ps->_array[i];
}
}
ps->_size -= count;
}
(16)顺序表冒泡排序
void SeqListBubbleSort(PSeq ps)//冒泡排序
{
for (int i = 0; i < ps->_size - 1; ++i)//控制冒泡总的趟数
{
int Ischange = 0;
for (int j = 0; j < ps->_size-1; ++j)
{
if (ps->_array[j] > ps->_array[j + 1])
{
Ischange = 1;
Swap(&ps->_array[j], &ps->_array[j + 1]);
}
}
}
}
(17)扩容
void CheckCapacity(PSeq ps)//检测容量
{
assert(ps);
if(ps->_size == ps->_capacity)//空间不够了
{
int newCapacity = ps->_capacity * 2;
//申请新空间
int* pTemp = (DataType*)malloc(newCapacity * sizeof(DataType));
if (pTemp == NULL)
{
assert(0);
return;
}
//realloc(p,size)
//拷贝元素
for(int i=0;i<ps->_size;++i)
{
pTemp[i] = ps->_array[i];
}
//释放旧空间
free(ps->_array);
//更新
ps->_array = pTemp;
ps->_capacity = newCapacity;
}
}
(18)销毁
void SeqListDestroy(PSeq ps)//销毁
{
if (ps->_array)
{
free(ps->_array);
ps->_array = NULL;
ps->_capacity = 0;
ps->_size = 0;
}
}
顺序表代码
头文件
#pragma once
//动态顺序表
typedef int DataType;
typedef struct SeqList
{
DataType* _array;
int _capacity;//顺序表的总大小
int _size;//顺序表中有效元素的个数
}SeqList, * PSeq;
void SeqListInit(PSeq ps, int capacity);//初始化
void SeqListPushBack(PSeq ps, DataType data);//尾插
void SeqListPopBack(PSeq ps);//尾删
void SeqListPushFront(PSeq ps, DataType data);//头插
void SeqListPopFront(PSeq ps);//头删
void SeqListInsert(PSeq ps, int pos,DataType data);//任意位置插
void SeqListErase(PSeq ps,int pos);//任意位置删
int SeqListFind(PSeq ps, DataType);//查找
int SeqListEmpty(PSeq ps);//是否为空
int SeqListSize(PSeq ps);//元素个数
int SeqListCapacity(PSeq ps);//容量大小
void SeqListClear(PSeq ps);//清空
void SeqListRemove(PSeq ps, DataType data);//移除第一个值为data的元素
void SeqListDestroy(PSeq ps);//销毁
void CheckCapacity(PSeq ps);//检测容量
void SeqListBubbleSort(PSeq ps);//冒泡排序
void SeqListRemoveAll(PSeq ps, DataType data);//移除所有值为data的元素
void TestSeqList();//测试
源文件
#include"SeqList.h"
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
void SeqListInit(PSeq ps, int capacity)
{
ps->_array = (DataType*)malloc(sizeof(DataType) * capacity);//申请空间
//malloc类型为void*,使用需要强制转换
if (NULL == ps->_array)//需要判空
{
assert(0);//仅调试时有用(debug版本)
return;
}
ps->_capacity = capacity;
ps->_size = 0;
}
void SeqListPushBack(PSeq ps, DataType data)//尾插
{
#if 0
assert(ps);
//顺序表满
CheckCapacity(ps);
ps->_array[ps->_size] = data;
ps->_size++;
#endif
SeqListInsert(ps, ps->_size, data);
}
void SeqListPopBack(PSeq ps)//尾删
{
#if 0
assert(ps);
if (SeqListEmpty(ps))
{
return;
}
ps->_size--;
#endif
SeqListErase(ps, ps->_size - 1);
}
void SeqListPushFront(PSeq ps, DataType data)//头插
{
#if 0
assert(ps);
CheckCapacity(ps);
for (int i = ps->_size - 1; i > 0; i--)
{
ps->_array[i+1] = ps->_array[i];
}
ps->_array[0] = data;
ps->_size++;
#endif
SeqListInsert(ps, 0 ,data);
}
void SeqListPopFront(PSeq ps)//头删
{
#if 0
if (SeqListEmpty(ps))
{
return;
}
for (int i = 1; i < ps->_size; ++i)
{
ps->_array[i-1]=ps->_array[i];
}
#endif
SeqListErase(ps, 0);
}
int SeqListEmpty(PSeq ps)
{
assert(ps);
return 0 == ps->_size;
}
void SeqListInsert(PSeq ps, int pos, DataType data)//任意位置插
{
assert(ps);
if (pos<0 || pos>ps->_size)
{
return;
}
CheckCapacity(ps);
for (int i = ps->_size - 1; i >= pos; i--)
{
ps->_array[i+1] = ps->_array[i];
}
ps->_array[pos] = data;
ps->_size++;
}
void SeqListErase(PSeq ps, int pos)//任意位置删
{
assert(ps);
if (pos<0||pos>ps->_size)
{
return;
}
for (int i = pos+1; i <ps->_size ; ++i)
{
ps->_array[i-1] = ps->_array[i];
}
ps->_size--;
}
int SeqListFind(PSeq ps, DataType data)//查找
{
assert(ps);
for (int i = 0; i < ps->_size; ++i)
{
if(ps->_array[i]==data)
{
return i;
}
}
return -1;
}
int SeqListSize(PSeq ps)//元素个数
{
assert(ps);
return ps->_size;
}
int SeqListCapacity(PSeq ps)//容量大小
{
assert(ps);
return ps->_capacity;
}
void SeqListClear(PSeq ps)//清空
{
assert(ps);
ps->_size = 0;
}
void SeqListRemove(PSeq ps, DataType data)//移除第一个值为data的元素
{
SeqListErase(ps, SeqListFind(ps, data));
}
void SeqListRemoveAll(PSeq ps, DataType data)//移除所有值为data的元素
{
assert(ps);
#if 0
int pos = -1;
while (-1!=(pos = SeqListFind(ps, data)))
{
SeqListErase(ps, pos);
}
#endif
int count=0;
for (int i = 0; i < ps->_size;++i)
{
if (data == ps->_array[i])
{
count++;
}
else
{
ps->_array[i - count] = ps->_array[i];
}
}
ps->_size -= count;
}
void Swap(int* pLeft, int* pRight)
{
int temp = *pLeft;
*pLeft = *pRight;
* pRight = temp;
}
void SeqListBubbleSort(PSeq ps)//冒泡排序
{
for (int i = 0; i < ps->_size - 1; ++i)//控制冒泡总的趟数
{
int Ischange = 0;
for (int j = 0; j < ps->_size-1; ++j)
{
if (ps->_array[j] > ps->_array[j + 1])
{
Ischange = 1;
Swap(&ps->_array[j], &ps->_array[j + 1]);
}
}
}
}
void CheckCapacity(PSeq ps)//检测容量
{
assert(ps);
if(ps->_size == ps->_capacity)//空间不够了
{
int newCapacity = ps->_capacity * 2;
//申请新空间
int* pTemp = (DataType*)malloc(newCapacity * sizeof(DataType));
if (pTemp == NULL)
{
assert(0);
return;
}
//realloc(p,size)
//拷贝元素
for(int i=0;i<ps->_size;++i)
{
pTemp[i] = ps->_array[i];
}
//释放旧空间
free(ps->_array);
//更新
ps->_array = pTemp;
ps->_capacity = newCapacity;
}
}
void SeqListPrint(PSeq ps)//打印顺序表
{
for (int i = 0; i < ps->_size; ++i)
{
printf("%d ", ps->_array[i]);
}
printf("\n");
}
void SeqListDestroy(PSeq ps)//销毁
{
if (ps->_array)
{
free(ps->_array);
ps->_array = NULL;
ps->_capacity = 0;
ps->_size = 0;
}
}
void TestSeqList()
{
SeqList s;
int pos = -1;
SeqListInit(&s,10);
SeqListPushBack(&s, 1);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 3);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 5);
SeqListPushBack(&s, 6);
SeqListPushBack(&s, 7);
SeqListPushBack(&s, 8);
SeqListPushBack(&s, 9);
SeqListPushBack(&s, 0);
printf("size=%d\n", SeqListSize(&s));
printf("capacity=%d\n", SeqListCapacity(&s));
SeqListPrint(&s);
SeqListPushBack(&s, 9);
printf("size=%d\n", SeqListSize(&s));
printf("capacity=%d\n", SeqListCapacity(&s));
SeqListPrint(&s);
SeqListPopBack(&s);
SeqListPrint(&s);
SeqListPushFront(&s, 0);
SeqListPrint(&s);
SeqListPopFront(&s);
SeqListPrint(&s);
SeqListInsert(&s, 1, 5);
SeqListPrint(&s);
pos = SeqListFind(&s, 5);
if (pos != -1)
{
printf("5 is in %d\n", pos);
}
else
{
printf("5 is not in %d\n", pos);
}
SeqListErase(&s, 1);
pos = SeqListFind(&s, 5);
if (pos != -1)
{
printf("5 is in %d\n", pos);
}
else
{
printf("5 is not in %d\n", pos);
}
SeqListPrint(&s);
printf("size=%d\n", SeqListSize(&s));
printf("capacity=%d\n", SeqListCapacity(&s));
SeqListDestroy(&s);
}
#include"SeqList.h"
int main()
{
TestSeqList();
return 0;
}