顺序表简介
顺序表是线性表的一种,线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表,链表,栈,队列,字符串…
顺序表是用一段物理地址连续的存储单元一次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删改查。顺序表一般分为:静态顺序表(使用定长数组存储),动态顺序表(使用动态开辟的数组存储)。
顺序表模拟实现
C语言版
#pragma once
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
/*---元素类型---*/
typedef int ElementType;
/*---顺序表---*/
typedef struct SeqList{
/*---指向动态开辟的空间---*/
ElementType* _sl;
/*---元素数量---*/
size_t _size;
/*---空间大小---*/
size_t _capacity;
} SeqList;
/*---初始化---*/
void Init(SeqList* sl){
assert(sl != NULL);
sl->_size = 0;
sl->_capacity = 1;
// 开辟空间
sl->_sl = (ElementType*)malloc(sizeof(ElementType) * sl->_capacity);
assert(sl->_sl != NULL);
}
/*---释放---*/
void Destory(SeqList* sl){
assert(sl != NULL);
// 释放空间
free(sl->_sl);
sl->_sl = NULL;
}
/*---扩容---*/
void EnlargeCapacity(SeqList* sl){
assert(sl != NULL);
// 如果元素数量大于或等于空间数量,进行扩容
if (sl->_size >= sl->_capacity){
sl->_capacity *= 2;
sl->_sl = (ElementType*)realloc(sl->_sl,
sl->_capacity * sizeof(ElementType));
assert(sl->_sl != NULL);
}
}
/*---尾插---*/
void PushBack(SeqList* sl, ElementType e){
assert(sl != NULL);
++sl->_size;
// 检查是否需要扩容
EnlargeCapacity(sl);
// 插入到队尾
sl->_sl[sl->_size - 1] = e;
}
/*---尾删---*/
void PopBack(SeqList* sl){
assert(sl != NULL);
// 将最后一个元素标记为无效即可
--sl->_size;
}
/*---头插---*/
void PushFront(SeqList* sl, ElementType e){
assert(sl != NULL);
++sl->_size;
// 检查是否需要扩容
EnlargeCapacity(sl);
// 现有元素集体向后移一个位置
for (int i = sl->_size; i > 0; --i){
sl->_sl[i - 1] = sl->_sl[i - 2];
}
// 将新元素放入0号位置
sl->_sl[0] = e;
}
/*---头删---*/
void PopFront(SeqList* sl){
assert(sl != NULL);
// 所有元素集体向前移动一个位置,将0号元素覆盖掉
for (int i = 0; i < (int)(sl->_size - 1); ++i){
sl->_sl[i] = sl->_sl[i + 1];
}
--sl->_size;
}
/*---查找---*/
int Find(const SeqList* sl, ElementType e){
assert(sl != NULL);
// 遍历查找,找到返回下标
for (int i = 0; i < (int)(sl->_size); ++i){
if (sl->_sl[i] == e){
return i;
}
}
// 未找到,返回-1
return -1;
}
/*---插入---*/
void Insert(SeqList* sl, int pos, ElementType e){
assert(sl != NULL);
// pos越界,直接返回
if (pos >= (int)(sl->_size)){
return;
}
++sl->_size;
// 检查是否需要扩容
EnlargeCapacity(sl);
// 将从pos往后的所有元素集体向后移动一个位置
for (int i = (int)(sl->_size); i > pos; --i){
sl->_sl[i] = sl->_sl[i - 1];
}
// 将元素放入pos位置
sl->_sl[pos] = e;
}
/*---擦除---*/
void Erase(SeqList* sl, size_t pos){
assert(sl != NULL);
// pos越界,直接返回
if (pos >= sl->_size){
return;
}
// 将从pos开始的所有元素集体向前移动一个位置,将pos覆盖掉
for (int i = pos; i < (int)(sl->_size) - 1; ++i){
sl->_sl[i] = sl->_sl[i + 1];
}
--sl->_size;
}
/*---移除---*/
void Remove(SeqList* sl, ElementType e){
assert(sl != NULL);
int pos = -1;
// 遍历查找e所在下标
for (int i = 0; i < (int)(sl->_size); ++i){
if (sl->_sl[i] == e){
pos = i;
break;
}
}
// 没找到,直接返回
if (pos == -1){
return;
}
// 移除pos位置的元素
Erase(sl, pos);
}
/*---移除所有---*/
void RemoveAll(SeqList* sl, ElementType e){
assert(sl != NULL);
// 保存剩下元素的数量
int cnt = 0;
// 遍历,把不等于e的元素放到数组中
for (int i = 0; i < (int)(sl->_size); ++i){
if (sl->_sl[i] != e){
sl->_sl[cnt] = sl->_sl[i];
++cnt;
}
}
sl->_size = cnt;
}
/*---修改---*/
void Modify(SeqList* sl, size_t pos, ElementType e){
assert(sl != NULL);
// pos位置越界,直接返回
if (pos >= sl->_size){
return;
}
sl->_sl[pos] = e;
}
/*---冒泡排序---*/
void BubbleSort(SeqList* sl){
assert(sl != NULL);
// 边界,bound之前为已序
for (int bound = 0; bound < (int)(sl->_size); ++bound){
// 当前位置
for (int cur = sl->_size - 1; cur > bound; --cur){
// 如果当前位置元素的值小于前一个值,交换
if (sl->_sl[cur] < sl->_sl[cur - 1]){
ElementType temp = sl->_sl[cur - 1];
sl->_sl[cur - 1] = sl->_sl[cur];
sl->_sl[cur] = temp;
}
}
}
}
/*---二分查找---*/
int BinarySearch(const SeqList* sl, ElementType e){
assert(sl != NULL);
// 计算左右位置
int left = 0;
int right = sl->_size - 1;
while (left <= right){
// 计算中间位置
int mid = left + (right - left) / 2;
// 中间位置值比目标值大
if (sl->_sl[mid] > e){
// 更新右
right = mid - 1;
}
// 中间位置值比目标值小
else if (sl->_sl[mid] < e){
// 更新左
left = mid + 1;
}
// 中间位置值和目标值相同
else{
return mid;
}
}
// 没找到,返回-1
return -1;
}
/*---顺序表打印---*/
void Display(const SeqList* sl){
assert(sl != NULL);
printf("The Sequence List is Below: \n");
// 遍历打印
for (int i = 0; i < (int)(sl->_size); ++i){
printf("%d\t", sl->_sl[i]);
}
printf("\n");
}
Java版
public class SeqList {
private int[] arr = new int[100];
private int size = 0;
// 清空
public void clear() {
this.size = 0;
this.arr = new int[100];
}
// 获取元素数量
public int size() {
return this.size;
}
// 删除全部指定元素
public void removeAll(int toRemove) {
int i = 0, j = 0;
for (; i < this.size; ++i) {
if (this.arr[i] != toRemove) {
this.arr[j++] = this.arr[i];
}
}
this.size = j;
}
// 删除指定元素
public void remove(int toRemove) {
int pos = this.search(toRemove);
if (pos == -1) {
return;
}
for (int i = pos; i < this.size - 1; ++i) {
this.arr[i] = this.arr[i + 1];
}
--this.size;
}
// 设置指定下标元素
public void setPos(int pos, int val) {
this.arr[pos] = val;
}
// 获取指定下标元素
public int getPos(int pos) {
return this.arr[pos];
}
// 是否包含
public boolean contains(int target) {
return this.search(target) != -1;
}
// 查找
public int search(int target) {
for (int i = 0; i < this.size; ++i) {
if (this.arr[i] == target) {
return i;
}
}
return -1;
}
// 添加
public void add(int pos, int val) {
if (pos < 0 || pos > this.size) {
return;
}
if (this.size >= this.arr.length) {
realloc();
}
for (int i = this.size; i > pos; --i) {
this.arr[i] = this.arr[i - 1];
}
this.arr[pos] = val;
++this.size;
}
// 扩容
private void realloc() {
int[] temp = new int[this.arr.length * 2];
for (int i = 0; i < this.size; ++i) {
temp[i] = this.arr[i];
}
this.arr = temp;
}
// 顺序表打印
public void display() {
System.out.print("[");
for (int i = 0; i < this.size; ++i) {
System.out.print(this.arr[i]);
if (i == this.size - 1) {
break;
}
System.out.print(", ");
}
System.out.println("]");
}
}