顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
- 静态顺序表:使用定长数组存储。
- 动态顺序表:使用动态开辟的数组存储。
SeqList.h
#ifndef __SeqList_H__
#define __SeqList_H__
//动态顺序表
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<assert.h>
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* _a;//数组
int _size;//数据个数
int _capacity;//容量
}SeqList;
void CheckCapacity(SeqList* psl);
void SeqListInit(SeqList* psl, int capacity);
void SeqListDestory(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);
void SeqListInsert(SeqList* psl,int pos, SLDataType x);
void SeqListErase(SeqList* psl, int pos);
void SeqListRemove(SeqList* psl, SLDataType x);
void SeqLsitModify(SeqList* psl, int pos, SLDataType x);
void SeqListPrint(SeqList* psl);
void Test();
//面试题
void SeqListBubbleSort(SeqList* psl);
int SeqListBinaryFind(SeqList* psl, SLDataType x);
//时间复杂度O(N), 空间复杂度 O(1)
void SeqListRemoveAll(SeqList* psl, SLDataType x);
#endif //__SeqList_H__
SeqList.c
#include "SeqList.h"
void SeqListInit(SeqList* psl, int capacity)
{
assert(psl);
if(capacity == 0)
{
psl->_a = NULL;
psl->_capacity = 0;
psl->_size = 0;
}
else
{
psl->_capacity = capacity;
psl->_size = 0;
psl->_a = (SLDataType*)malloc(sizeof(SLDataType)*capacity);
assert(psl->_a);
}
}
void SeqListDestory(SeqList* psl)
{
assert(psl);
free(psl->_a);
psl->_a = NULL;
psl->_capacity = psl->_size = 0;
}
void CheckCapacity(SeqList* psl)
{
if(psl->_capacity == psl->_size)
{
SLDataType* tmp = NULL;
if(psl->_capacity == 0)
{
psl->_capacity = 2;
}
tmp = realloc(psl->_a, sizeof(SLDataType)*psl->_capacity*2);
assert(tmp);
psl->_a = tmp;
psl->_capacity *= 2;
}
}
void SeqListPushBack(SeqList* psl, SLDataType x)
{
assert(psl);
CheckCapacity(psl);
psl->_a[psl->_size] = x;
psl->_size++;
}
void SeqListPopBack(SeqList* psl)
{
assert(psl);
if(psl->_size > 0)
{
psl->_size--;
}
}
void SeqListPushFront(SeqList* psl, SLDataType x)
{
int n = 0;
assert(psl);
n = psl->_size;
while(n)
{
psl->_a[n] = psl->_a[n-1];
n--;
}
psl->_a[0] = x;
psl->_size++;
}
void SeqListPopFront(SeqList* psl)
{
int i = 0;
int n = psl->_size-1;
if(psl->_size == 0)
return ;
while(n)
{
psl->_a[i] = psl->_a[i+1];
n--;
i++;
}
psl->_size--;
}
void SeqListInsert(SeqList* psl, int pos, SLDataType x)
{
int n = 0;
int m = psl->_size;
CheckCapacity(psl);
assert(psl && pos < psl->_size);
n = psl->_size - pos;
while(n)
{
psl->_a[m] = psl->_a[m-1];
n--;
}
psl->_a[pos] = x;
psl->_size++;
}
void SeqListErase(SeqList* psl, int pos)
{
int n = 0;
int m = pos;
assert(psl && pos < psl->_size);
n = psl->_size - pos;
while(n)
{
psl->_a[m] = psl->_a[m+1];
n--;
m++;
}
psl->_size--;
}
int SeqListFind(SeqList* psl, SLDataType x)
{
int i = 0;
assert(psl);
for(i=0; i<psl->_size; i++)
{
if(psl->_a[i] == x)
return i;
}
return -1;
}
void SeqListRemove(SeqList* psl, SLDataType x)
{
int pos = 0;
assert(psl);
pos = SeqListFind(psl, x);
if(pos != -1)
{
SeqListErase(psl, pos);
}
}
void SeqListPrint(SeqList* psl)
{
int i = 0;
assert(psl);
for(i=0; i<psl->_size; i++)
{
printf("%d ", psl->_a[i]);
}
printf("\n");
}
void SeqListModify(SeqList* psl, int pos, SLDataType x)
{
assert(psl && pos < psl->_size);
psl->_a[pos] = x;
}
void SeqListBubbleSort(SeqList* psl)
{
int i = 0;
int j = 0;
int tmp = 0;
int flag = 0;
int begin = 0;
int end = psl->_size;
assert(psl);
/*for(i=psl->_size; i>0; i--)
{
flag = 0;
for(j=0; j<i-1; j++)
{
if(psl->_a[j] > psl->_a[j+1])
{
flag = 1;
tmp = psl->_a[j];
psl->_a[j] = psl->_a[j+1];
psl->_a[j+1] = tmp;
}
}
if(flag == 0)
break;
}*/
while(end>0)
{
begin = 1;
while(begin < end)
{
if(psl->_a[begin-1] > psl->_a[begin])
{
tmp = psl->_a[begin-1];
psl->_a[begin-1] = psl->_a[begin];
psl->_a[begin] = tmp;
}
begin++;
}
end--;
}
}
int SeqListBinaryFind(SeqList* psl, SLDataType x)
{
/*int left = 0;
int right = psl->_size-1;
int mid = left + (right - left)/2;
while(left <= right)
{
mid = left + (right-left)/2;
if(psl->_a[mid] < x)
{
left = mid + 1;
}
else if(psl->_a[mid] > x)
{
right = mid -1;
}
else
{
return mid;
}
}
return -1;*/
//在数组区间左闭右开时,右边不减一,否则会导致元素被跳过
int left = 0;
int right = psl->_size;
int mid = left + (right - left)/2;
while(left < right)
{
mid = left + (right-left)/2;
if(psl->_a[mid] < x)
{
left = mid+1;
}
else if(psl->_a[mid] > x)
{
right = mid;
}
else
{
return mid;
}
}
return -1;
}
void SeqListRemoveAll(SeqList* psl, SLDataType x)
{
int i = 0;
int j = 0;
assert(psl);
for(i=0; i<psl->_size; i++)
{
if(psl->_a[i] != x)
{
psl->_a[j] = psl->_a[i];
j++;
}
}
psl->_size = j;
}
void Test()
{
int i = 0;
SeqList s;
SeqListInit(&s, 1);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 3);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 4);
SeqListPushBack(&s, 5);
SeqListPushBack(&s, 7);
SeqListPushBack(&s, 2);
SeqListPushBack(&s, 1);
/*SeqListPushFront(&s, 2);
SeqListPopFront(&s);
SeqListInsert(&s, 2, 2);
SeqListErase(&s, 3);
SeqListRemove(&s,2 );
SeqListModify(&s, 0, 80);*/
//SeqListBubbleSort(&s);
/*i = SeqListBinaryFind(&s, 2);
if(i != -1)
{
printf("找到了\n");
}
else
{
printf("没找到\n");
}*/
SeqListRemoveAll(&s, 2);
SeqListPrint(&s);
}