顺序表的介绍和实现
线性表是我们认识的第一种数据结构,线性表其实包含有两种数据结构,一种是顺序表,一种是链表 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储 线性表是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串 顺序表的本质其实就是一个数组
顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改 顺序表又分为静态顺序表和动态顺序表,主要的区别还是在于存储元素个数的灵活性的问题;静态顺序表:使用定长数组存储元素,动态顺序表:使用动态开辟的数组存储 静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,下面是静态顺序表
程序的实现大致分为三个部分
SeqList.h
# pragma once
# include <stdio.h>
# include <stdlib.h>
# include <assert.h>
# include <string.h>
# define DefaultCapacity 20
typedef int DataType;
typedef struct SeqList
{
DataType* array;
int _size;
int _capacity;
} SeqList;
void SeqListInit ( SeqList* seq) ;
void SeqListPrint ( SeqList* seq) ;
void SeqListDestroy ( SeqList* seq) ;
void SeqListPushBack ( SeqList* seq, DataType data) ;
void SeqListPopBack ( SeqList* seq) ;
void SeqListPushFront ( SeqList* seq, DataType data) ;
void SeqListPopFront ( SeqList* seq) ;
void SeqListInsert ( SeqList* seq, int index, DataType data) ;
void SeqListErase ( SeqList* seq, int index) ;
int SeqListFind ( SeqList* seq, DataType data) ;
void SeqListRemove ( SeqList* seq, DataType data) ;
void SeqListRemoveAll ( SeqList* seq, DataType data) ;
int SeqSize ( SeqList* seq) ;
int SeqCapacity ( SeqList* seq) ;
int SeqListEmpty ( SeqList* seq) ;
DataType SeqListFront ( SeqList* seq) ;
DataType SeqListLast ( SeqList* seq) ;
SeqList.c
# include "SeqList.h"
static void CheckCapacity ( SeqList * seq)
{
assert ( seq != NULL ) ;
if ( seq-> _size == seq-> _capacity)
{
int newCapacity = 2 * DefaultCapacity;
DataType* newArray = ( DataType* ) malloc ( sizeof ( DataType) * newCapacity) ;
if ( NULL == newArray)
{
assert ( 0 ) ;
return ;
}
memcpy ( newArray, seq-> array, seq-> _size * sizeof ( DataType) ) ;
free ( seq-> array) ;
seq-> array = newArray;
seq-> _capacity = newCapacity;
}
}
void SeqListInit ( SeqList* seq)
{
assert ( seq != NULL ) ;
seq-> array = ( DataType* ) malloc ( sizeof ( DataType) * DefaultCapacity) ;
if ( NULL == seq-> array)
{
assert ( 0 ) ;
return ;
}
seq-> _size = 0 ;
seq-> _capacity = DefaultCapacity;
}
void SeqListDestroy ( SeqList* seq)
{
free ( seq-> array) ;
seq-> array = NULL ;
seq-> _size = 0 ;
seq-> _capacity = 0 ;
}
void SeqListPushBack ( SeqList* seq, DataType data)
{
assert ( seq != NULL ) ;
CheckCapacity ( seq) ;
seq-> array[ seq-> _size] = data;
seq-> _size++ ;
}
void SeqListPopBack ( SeqList* seq)
{
assert ( seq != NULL ) ;
if ( 0 == seq-> _size)
return ;
seq-> _size-- ;
}
void SeqListPrint ( SeqList* seq)
{
assert ( seq) ;
int i = 0 ;
for ( i = 0 ; i < seq-> _size; i++ )
{
printf ( "%d " , seq-> array[ i] ) ;
}
printf ( "\n" ) ;
}
void SeqListPushFront ( SeqList* seq, DataType data)
{
assert ( seq != NULL ) ;
CheckCapacity ( seq) ;
for ( int i = seq-> _size- 1 ; i >= 0 ; i-- )
{
seq-> array[ i + 1 ] = seq-> array[ i] ;
}
seq-> array[ 0 ] = data;
seq-> _size++ ;
}
void SeqListPopFront ( SeqList* seq)
{
assert ( seq != NULL ) ;
if ( 0 == seq-> _size)
return ;
else
{
for ( int i = 0 ; i <= seq-> _size- 2 ; i++ )
{
seq -> array[ i] = seq-> array[ i + 1 ] ;
}
}
seq-> _size-- ;
}
void SeqListInsert ( SeqList* seq, int index, DataType data)
{
assert ( seq != NULL ) ;
if ( index< 0 || index> seq-> _size)
{
printf ( "所输入的下标为非法下标,请重新输入!" ) ;
return ;
}
CheckCapacity ( seq) ;
for ( int i = seq-> _size - 1 ; i >= index; i-- )
{
seq-> array[ i + 1 ] = seq-> array[ i] ;
}
seq-> array[ index] = data;
seq-> _size++ ;
}
void SeqListErase ( SeqList* seq, int index)
{
assert ( seq != NULL ) ;
if ( index< 0 || index> seq-> _size)
{
printf ( "所输入的下标为非法下标,请重新输入!" ) ;
return ;
}
for ( int i = index; i <= seq-> _size - 2 ; i++ )
{
seq-> array[ i] = seq-> array[ i + 1 ] ;
}
seq-> _size-- ;
}
int SeqListFind ( SeqList* seq, DataType data)
{
assert ( seq != NULL ) ;
for ( int i = 0 ; i < seq-> _size; i++ )
{
if ( seq-> array[ i] == data)
return i;
}
return - 1 ;
}
void SeqListRemove ( SeqList* seq, DataType data)
{
assert ( seq != NULL ) ;
SeqListErase ( seq, SeqListFind ( seq, data) ) ;
}
void SeqListRemoveAll ( SeqList* seq, DataType data)
{
assert ( seq != NULL ) ;
int index = - 1 ;
while ( - 1 == SeqListFind ( seq, data) )
{
SeqListErase ( seq, index) ;
}
}
int SeqListSize ( SeqList* seq)
{
assert ( seq != NULL ) ;
return seq-> _size;
}
int SeqListCapacity ( SeqList* seq)
{
assert ( seq != NULL ) ;
return seq-> _capacity;
}
int SeqListEmpty ( SeqList* seq)
{
assert ( seq != NULL ) ;
if ( 0 == seq-> _size)
return 1 ;
else
return 0 ;
}
DataType SeqListFront ( SeqList* seq)
{
assert ( seq != NULL ) ;
return seq-> array[ 0 ] ;
}
DataType SeqListLast ( SeqList* seq)
{
assert ( seq != NULL ) ;
return seq-> array[ seq-> _size - 1 ] ;
}
main.c
# include "SeqList.h"
int main ( )
{
SeqList Seq;
SeqListInit ( & Seq) ;
SeqListPushBack ( & Seq, 1 ) ;
SeqListPushBack ( & Seq, 2 ) ;
SeqListPushBack ( & Seq, 3 ) ;
SeqListPushBack ( & Seq, 4 ) ;
SeqListPushBack ( & Seq, 5 ) ;
SeqListPrint ( & Seq) ;
SeqListPopBack ( & Seq) ;
SeqListPopBack ( & Seq) ;
SeqListPrint ( & Seq) ;
SeqListPushFront ( & Seq, 10 ) ;
SeqListPushFront ( & Seq, 20 ) ;
SeqListPushFront ( & Seq, 30 ) ;
SeqListPushFront ( & Seq, 40 ) ;
SeqListPushFront ( & Seq, 50 ) ;
SeqListPrint ( & Seq) ;
SeqListPopFront ( & Seq) ;
SeqListPopFront ( & Seq) ;
SeqListPopFront ( & Seq) ;
SeqListPrint ( & Seq) ;
SeqListInsert ( & Seq, 3 , 46 ) ;
SeqListPrint ( & Seq) ;
SeqListErase ( & Seq, 3 ) ;
SeqListPrint ( & Seq) ;
SeqListFind ( & Seq, 30 ) ;
printf ( "%d\n" , SeqListSize ( & Seq) ) ;
printf ( "%d\n" , SeqListCapacity ( & Seq) ) ;
SeqListDestroy ( & Seq) ;
return 0 ;
}
相关OJ
题目一:移除元素
拿到这个题目如如果忽略掉题目的要求的话,就是可以使用两个数组来对这个问题进行求解的,把等于那个元素的值的元素放在另外一个数组,剩下的元素就是符合条件的元素,可以直接返回另一个数组,就是满足条件的,但是这样不符合题目的要求,这种算法的时间复杂度和空间复杂度都是O(N),所以相当于是用空间换时间的方法 另一种解法,其实就是在原先的数组中进行相应的操作,使用两个指针进行来进行求解
class Solution {
public:
int removeElement ( vector< int > & nums, int val) {
int n = nums. size ( ) ;
int left = 0 ;
for ( int right = 0 ; right < n; right++ ) {
if ( nums[ right] != val) {
nums[ left] = nums[ right] ;
left++ ;
}
}
return left;
}
} ;