赞
踩
大家都知道要学好编程,数据结构是十分重要的一门课,而线性表是一种在实际中广泛使用的数据结构,那么线性表是什么呢,线性表是n个具有相同特性(数据类型)的数据元素的有限序列,常见的线性表有:顺序表、链表、栈、队列、字符串…但不要误会的是线性表在逻辑上是线性结构,也就是一条连续的直线,但在物理结构上不一定是连续的,所以线性表在物理上存储时,通常以数组和链式结构形式存储,下面我们就来学习一下线性表中的顺序表吧。
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成数据的增删查改
代码如下(示例):
//静态顺序表
struct SArrayList
{
DataType array[MAX];//存储数据的数组
int size; // 有效的数据的个数
};
代码如下(示例):
//动态顺序表
struct DArrayList
{
DataType* pointer;//指向动态开辟的数组
int size;//有效数据的个数
int capacity;//最大容量
};
//动态顺序表
typedef struct SeqList
{
SLDateType* array;
int size;
int capacity;
}SeqList;
//SeqList.h #pragma once #include<stdio.h> #include<iostream> #include<assert.h> #include<stdlib.h> using namespace std; typedef int SLDataType; typedef struct SeqList { SLDataType* array; // 动态开辟数组 int size;//有效数据个数 int capacity;//最大容量 }SeqList; //初始化 void SeqListInit(SeqList* psl); // 检查空间,如果满了,进行增容 void CheckCapacity(SeqList* psl); // 顺序表尾插 void SeqListPushBack(SeqList* psl, SLDataType x); // 顺序表尾删 void SeqListPopBack(SeqList* psl); // 顺序表头插 void SeqListPushFront(SeqList* psl, SLDataType x); // 顺序表头删 void SeqListPopFront(SeqList* psl); // 顺序表查找 int SeqListFind(SeqList* psl, SLDataType x); // 顺序表在pos位置插入x void SeqListInsert(SeqList* psl, size_t pos, SLDataType x); // 顺序表删除pos位置的值 void SeqListErase(SeqList* psl, size_t pos); // 顺序表销毁 void SeqListDestory(SeqList* psl); // 顺序表打印 void SeqListPrint(SeqList* psl);
//SeqList.cpp #include"SeqList.h" //初始化 void SeqListInit(SeqList* psl) { psl->array = NULL; psl->size = 0; psl->capacity = 0; } // 检查空间,如果满了,进行增容 void CheckCapacity(SeqList* psl) { assert(psl); if (psl->size == psl->capacity) { //增容 int newCapacity = (psl->capacity == 0) ? 4 : (2 * psl->capacity); SLDataType* tmp = NULL; tmp = (SLDataType*)realloc(psl->array,sizeof(SLDataType) * newCapacity); if (tmp == NULL) { perror("realloc fail"); exit(-1); } psl->capacity = newCapacity; psl->array = tmp; } } // 顺序表尾插 时间复杂度O(1) void SeqListPushBack(SeqList* psl, SLDataType x) { assert(psl); CheckCapacity(psl); //尾插 psl->array[psl->size] = x; psl->size++; } // 顺序表打印 时间复杂度O(N) void SeqListPrint(SeqList* psl) { assert(psl); for (int i = 0; i < psl->size; i++) { cout << psl->array[i] << " "; } } // 顺序表尾删 时间复杂度O(1) void SeqListPopBack(SeqList* psl) { assert(psl); if (psl->size == 0) { cout << "已经是空表" << endl; return; } psl->size--; } // 顺序表头插 时间复杂度O(N) void SeqListPushFront(SeqList* psl, SLDataType x) { assert(psl); CheckCapacity(psl); for (int i = psl->size - 1; i >= 0; i--) { psl->array[i + 1] = psl->array[i]; } psl->array[0] = x; psl->size++; } // 顺序表头删 时间复杂度O(N) void SeqListPopFront(SeqList* psl) { assert(psl); if (psl->size == 0) { cout << "已经是空表" << endl; return; } for (int i = 1; i < psl->size; i++) { psl->array[i - 1] = psl->array[i]; } psl->size--; } // 顺序表查找 时间复杂度O(N) int SeqListFind(SeqList* psl, SLDataType x) { assert(psl); for (int i = 0; i < psl->size; i++) { if (psl->array[i] == x) { return i; } } return -1; } // 顺序表在pos位置插入x void SeqListInsert(SeqList* psl, size_t pos, SLDataType x) { assert(psl); assert(pos <= psl->size); CheckCapacity(psl); //注意:这里i要用size_t类型,如果用int型,在比较i>=pos的时候会把int型转化为size_t类型再进行比较 for (size_t i = psl->size - 1; i >= pos; i--) { psl->array[i + 1] = psl->array[i]; } psl->array[pos] = x; psl->size++; } // 顺序表删除pos位置的值 void SeqListErase(SeqList* psl, size_t pos) { assert(psl); assert(pos <= psl->size-1); if (psl->size == 0) { cout << "已经是空表" << endl; return; } for (size_t i = pos + 1; i < psl->size; i++) { psl->array[i - 1] = psl->array[i]; } psl->size--; } // 顺序表销毁 void SeqListDestory(SeqList* psl) { assert(psl); free(psl->array); psl->capacity = 0; psl->size = 0; }
//test.cpp #include"SeqList.h" void SeqListTest1() { SeqList sl; SeqListInit(&sl); SeqListPushBack(&sl, 1); SeqListPushBack(&sl, 1); SeqListPushBack(&sl, 1); SeqListPushBack(&sl, 1); SeqListPushBack(&sl, 2); SeqListPushFront(&sl, 7); SeqListPushFront(&sl, 7); SeqListPushFront(&sl, 7); SeqListInsert(&sl, 2, 9); SeqListErase(&sl, 2); SeqListErase(&sl, 2); SeqListErase(&sl, 2); SeqListErase(&sl, 2); SeqListErase(&sl, 2); SeqListErase(&sl, 2); SeqListErase(&sl, 2); SeqListPrint(&sl); SeqListDestory(&sl); free(&sl); SeqListPrint(&sl); } int main() { SeqListTest1(); return 0; }
学完顺序表我们发现,虽然顺序表对于存取数据较快,但是同时也存在着许多问题,例如中间头部的插入删除时间复杂度较高,扩容的时候需要申请新的空间,拷贝数据,释放旧空间,这会造成大量的消耗,而且扩容一般是呈2倍的增长,会有一定的空间浪费,那么就没有更好的数据结构能够解决这些问题了吗,答案是有的,它就是我们数据结构中的链表,我会在下次博客中揭晓链表的结构与顺序表相比其优缺点。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。