线性表
定义一张顺序表也就是在内存中开辟一段连续的存储空间,并给它一个名字进行标识。只有定义了一个顺序表,才能利用该顺序表存放数据元素,也才能对该顺序表进行各种操作。
静态顺序表结构如下:
#define MAX_SIZE 100
typedef int DataType;
typedef struct SeqList
{
DataType array[MAX_SIZE];
int size;
}SeqList;
静态顺序表的一些基本操作实现如下:
void InitSeqList(SeqList* pSeq)
{
assert(pSeq);
memset(pSeq->array, 0, MAX_SIZE*sizeof(DataType));
pSeq->size = 0;
}
void PrintSeqList(SeqList* pSeq)
{
assert(pSeq);
int i = 0;
for (; i < pSeq->size; i++)
{
printf("%d ",pSeq->array[i]);
}
printf("\n");
}
void PushBack(SeqList* pSeq, DataType data)
{
assert(pSeq);
if (pSeq->size == MAX_SIZE)
{
printf("Capacity Is Full\n");
return;
}
pSeq->array[pSeq->size++] = data;
}
void PopBack(SeqList* pSeq)
{
assert(pSeq);
if (pSeq->size == 0)
{
printf("Capacity Is Empty\n");
return;
}
pSeq->size--;
}
void PushFront(SeqList* pSeq,DataType data)
{
assert(pSeq);
if (pSeq->size == MAX_SIZE)
{
printf("Capacity Is Full\n");
return;
}
int i = pSeq->size - 1;
for (; i >= 0; i--)
{
pSeq->array[i + 1] = pSeq->array[i];
}
pSeq->array[0] = data;
pSeq->size++;
}
void PopFront(SeqList* pSeq)
{
assert(pSeq);
if (pSeq->size == 0)
{
printf("Capacity Is Empty\n");
return;
}
int i = 0;
for (; i < pSeq->size - 1; i++)
{
pSeq->array[i] = pSeq->array[i + 1];
}
pSeq->size--;
}
void Insert(SeqList* pSeq, int index, DataType data)
{
assert(pSeq);
if (pSeq->size == MAX_SIZE)
{
printf("Capacity Is Full\n");
return;
}
int i = pSeq->size - 1;
for (; i >= index; i--)
{
pSeq->array[i + 1] = pSeq->array[i];
}
pSeq->array[index] = data;
pSeq->size++;
}
void Modified(SeqList* pSeq,int index, DataType data)
{
assert(pSeq);
if (index < 0 || index > pSeq->size - 1)
{
printf("Invaid Index\n");
return;
}
pSeq->array[index] = data;
}
void Removed(SeqList* pSeq, int index)
{
assert(pSeq);
if (index < 0 || index > pSeq->size - 1)
{
printf("Invaid Index\n");
return;
}
int i = index;
for (; i < pSeq->size - 1; i++)
{
pSeq->array[i] = pSeq->array[i + 1];
}
pSeq->size--;
}
typedef enum TAG
{
TRUE,
FALSE,
}TAG;
TAG tag;
typedef struct FindRet
{
TAG Is_Find;
int index;
}FindRet;
FindRet ret;
FindRet Find(SeqList* pSeq, DataType data , int index)
{
assert(pSeq);
ret.Is_Find = FALSE;
if (index < 0 || index > pSeq->size - 1)
{
printf("Invaid Index\n");
return ret;
}
for (; index < pSeq->size; index++)
{
if (pSeq->array[index] == data)
{
ret.Is_Find = TRUE;
ret.index = index;
return ret;
}
}
return ret;
}
TAG Erase(SeqList* pSeq, DataType data, TAG all)
{
assert(pSeq);
tag = FALSE;
ret = Find(pSeq,data,0);
while (ret.Is_Find == TRUE)
{
tag = TRUE;
Removed(pSeq,ret.index);
if (all == FALSE)
{
break;
}
ret = Find(pSeq, data, ret.index);
}
return tag;
}
动态顺序表结构如下:
#define EXPLAND_CAPACITY 10
typedef int DataType;
typedef struct SeqList
{
DataType* elem;
int size;
int capacity;
}SeqList;
动态顺序表的一些基本操作实现如下::
void InitSeqList(SeqList* pSeq)
{
pSeq->elem = (DataType*)malloc(EXPLAND_CAPACITY*sizeof(DataType));
pSeq->capacity = EXPLAND_CAPACITY;
pSeq->size = 0;
}
void PrintSeqList(SeqList* pSeq)
{
assert(pSeq);
int i = 0;
for (; i < pSeq->size; i++)
{
printf("%d ", pSeq->elem[i]);
}
printf("\n");
}
void Expland_Capacity(SeqList* pSeq) //扩大容量
{
assert(pSeq);
if (pSeq->size == pSeq->capacity)
{
pSeq->capacity = pSeq->capacity * 2;
DataType* newelem = (DataType*)malloc(pSeq->capacity*sizeof(DataType));
memcpy(newelem, pSeq->elem, pSeq->size*sizeof(DataType));
free(pSeq->elem);
pSeq->elem = newelem;
}
}
void PushBack(SeqList* pSeq, DataType data)
{
assert(pSeq);
Expland_Capacity(pSeq);
pSeq->elem[pSeq->size++] = data;
}
void PopBack(SeqList* pSeq)
{
assert(pSeq);
if (pSeq->size > 0)
{
pSeq->size
}
}
void PushFront(SeqList* pSeq,DataType data)
{
assert(pSeq);
Expland_Capacity(pSeq);
int i = pSeq->size - 1;
for (; i >= 0; i
{
pSeq->elem[i + 1] = pSeq->elem[i];
}
pSeq->elem[0] = data;
pSeq->size++;
}
void PopFront(SeqList* pSeq)
{
assert(pSeq);
if (pSeq->size == 0)
{
printf("Capacity Is Empty\n");
return;
}
int i = 0;
for (; i < pSeq->size - 1; i++)
{
pSeq->elem[i] = pSeq->elem[i + 1];
}
pSeq->size
}
void BubbleSort(SeqList* pSeq) //冒泡排序
{
assert(pSeq);
int i, j;
int count = 0;
int flag = 0;
for (i = 0; i < pSeq->size - 1; i++)
{
for (j = 0; j < pSeq->size - 1 - i; j++)
{
if (pSeq->elem[j]>pSeq->elem[j + 1])
{
int tmp = pSeq->elem[j];
pSeq->elem[j] = pSeq->elem[j + 1];
pSeq->elem[j + 1] = tmp;
flag = 1;
count++; //计算交换次数
}
}
if (flag == 0) //如果第一轮比较没有交换过,说明是序列本来是升序的
{
printf("count = %d\n", count);
break;
}
flag = 0;
}
}
void SeleSort(SeqList* pSeq) //选择排序
{
assert(pSeq);
int i,j,k;
for (i = 0; i < pSeq->size - 1; i++)
{
k = i;
for (j = i + 1; j < pSeq->size; j++)
{
if (pSeq->elem[k] > pSeq->elem[j])
{
k = j;
}
}
if (k != i)
{
int tmp = pSeq->elem[k];
pSeq->elem[k] = pSeq->elem[i];
pSeq->elem[i] = tmp;
}
}
}
int BinarySearch(SeqList* pSeq,DataType data) //二分查找
{
assert(pSeq);
int lift = 0;
int right = pSeq->size - 1;
int mid = lift + (right - lift) / 2;//防止相加发生溢出
while (lift <= right)
{
mid = lift + (right - lift) / 2;
if (pSeq->elem[mid] == data)
{
return mid;
}
else if (pSeq->elem[mid] > data)
{
right = mid - 1;
}
else
{
lift = mid + 1;
}
}
return -1;
}
线性表优点是:
无须为表示表中元素之间的逻辑关系增加额外的存储空间;
可以方便地随机访问表中任一位置的元素。
缺点是:
插入和删除运算不方便,除表尾的位置外,在表的其他位置上进行插入或删除操作都必须移动大量元素,其效率较低;
由于数组要求占用连续的存储空间,存储分配只能预先进行静态分配。因此,当表长变化较大时,难以确定数组的合适的大小。确定大了将造成浪费。