线性表之C语言实现(顺序表)

线性表之顺序表

线性表

1、线性表是包含若干数据元素的一个线性序列。记为:
L = ( a 0 , . . . . . . a i − 1 , a i , a i + 1 , . . . . . . a n − 1 ) L 为表名, a i ( 0 ≤ i ≤ n − 1 ) 为数据元素; n 为表长, n ≥ 0 时,线性表 L 为非空表,否则为空表。 L=(a_0,......a_{i-1},a_i,a_{i+1},......a_{n-1}) \\L为表名,a_i(0\leq i \leq n-1)为数据元素; \\n为表长,n\geq 0时,线性表L为非空表,否则为空表。 L=(a0,......ai1,ai,ai+1,......an1)L为表名,ai(0in1)为数据元素;n为表长,n0时,线性表L为非空表,否则为空表。
线性表L可用二元组形式描述:L=(D,R);即Data,Relation。

即线性表L包含数据元素集合D和关系集合R。
D = { a i ∣ a i ∈ d a t a t y p e , i = 0 , 1 , 2 ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ n − 1 , n ≥ 0 } R = { a i , a i + 1 > ∣ a i , a i + 1 ∈ D , 0 ≤ i ≤ n − 2 } D=\{ a_i|a_i∈datatype,i=0,1,2······n-1,n\geq0\}\\ R=\{ a_i,a_{i+1}>|a_i,a_{i+1}∈D,0\leq i \leq n-2\} D={aiaidatatype,i=0,1,2⋅⋅⋅⋅⋅⋅n1,n0}R={ai,ai+1>ai,ai+1D,0in2}
关系符 < a i , a i + 1 > <a_i,a_{i+1}> <ai,ai+1>在这里称为有序对
表示任意相邻的两元素之间的一种先后次序关系。
a i a_i ai a i + 1 a_{i+1} ai+1的直接前驱, a i + 1 a_{i+1} ai+1 a i a_i ai​的直接后继。

2、线性表的特征

1
2
3
4
5
6
  1. 对非空表, a 0 a_0 a0是表头,无前驱;
  2. a n − 1 a_{n-1} an1是表尾,无后继;
  3. 其它的每个元素 a i a_i ai有且仅有一个直接前驱 a i − 1 a_{i-1} ai1和一个直接后继 a i + 1 a_{i+1} ai+1

线性表顺序存储

1、顺序存储结构的表示

若将线性表 L = ( a 0 , a 1 , … … , a n − 1 ) L=(a_0,a_1, ……,a_{n-1}) L=(a0,a1,……,an1)中的各元素依次存储于计算机一片连续的存储空间。

2、顺序存储结构的特点

  • 逻辑上相邻的元素 a i , a i + 1 a_i, a_{i+1} ai,ai+1,其存储位置也是相邻的。
  • 对数据元素 a i a_i ai的存取为随机存取或按地址存取。
  • 存储密度高:存储密度D=(数据结构中元素所占存储空间)/(整个数据结构所占空间)。

3、顺序存储结构的不足

  • 对表的插入和删除等运算的时间复杂度较差。

应用场景:在C语言中,可以借助一维数组类型来描述线性表的顺序存储结构。如:

//线性表的顺序存储结构
#define  N 100       
typedef   int  data_t;
typedef  struct                     
{   data_t data[N]//表的存储空间
     int last;   
}   sqlist, *sqlink;   	

设计功能

1、线性表的基本运算

设线性表 L = ( a 0 , a 1 , … … , a n − 1 ) L=(a_0,a_1, ……,a_{n-1}) L=(a0,a1,……,an1),对 L的基本运算有:

1)建立一个空表:list_create(L)

2)置空表:list_clear(L)

3)判断表是否为空:list_empty (L)。若表为空,返回值为1 , 否则返回 0

4)求表长:length (L)

5)取表中某个元素:GetList(L , i ), 即 a i a_i ai。要求0≤i≤length(L)-1

6)定位运算:Locate(L,x)。确定元素x在表L中的位置(或序号)

L o c a t e ( L , x ) = { i         当元素 x = a i ∈ L , 且 a i 是第一个与 x 相等时; − 1       x 不属于 L 时。 Locate(L,x)= \left\{ \begin{array}{l} i~~~~~~~~当元素x=ai∈L,且ai是第一个与x相等时;\\ -1 ~~~~~ x不属于L时。 \end{array} \right. Locate(L,x)={i        当元素x=aiL,ai是第一个与x相等时;1     x不属于L时。
7)插入:

Insert(L,x,i)。将元素x插入到表L中第i个元素ai之前,且表长+1。

插入前: ( a 0 , a 1 , . . . , a i − 1 , a i , a i + 1 . . . , a n − 1 ) (a_0,a_1,...,a_{i-1},a_i,a_{i+1}...,a_{n-1}) (a0,a1,...,ai1,ai,ai+1...,an1) 0≤i≤n,i=n时,x插入表尾

插入后: ( a 0 , a 1 , . . . , a i − 1 , x , a i , a i + 1 . . . , a n − 1 ) (a_0,a_1,...,a_{i-1}, x, a_i,a_{i+1}...,a_{n-1}) (a0,a1,...,ai1,x,ai,ai+1...,an1)

8)删除:

Delete(L,i)。删除表L中第i个元素ai,且表长减1, 要求0≤i≤n-1。

删除前: ( a 0 , a 1 , . . . , a i − 1 , a i , a i + 1 . . . , a n − 1 ) (a_0,a_1,...,a_{i-1},a_i,a_{i+1}...,a_{n-1}) (a0,a1,...,ai1,ai,ai+1...,an1)

删除后: ( a 0 , a 1 , . . . , a i − 1 , a i + 1 . . . , a n ) (a_0,a_1,...,a_{i-1},a_{i+1}...,a_n) (a0,a1,...,ai1ai+1...,an)

代码

test.c

#include <stdio.h>
#include "sqlist.h"

void test_insert();
void test_delete();
void test_merge();
void test_purge();

int main(int argc, char *argv[])
{
	//test_insert();
	//test_delete();
	//test_merge();
	test_purge();

	return 0;
}

void test_insert()
{
	sqlink L;
	L = list_create();

	if(NULL == L)
		return;

	list_insert(L, 10, 0);
	list_insert(L, 20, 0);
	list_insert(L, 30, 0);
	list_insert(L, 40, 0);
	list_insert(L, 50, 0);
	list_insert(L, 60, 0);
	list_show(L);

	list_insert(L, 100, 0);
	list_show(L);
	list_free(L);
}

void test_delete()
{
	sqlink L;
	L = list_create();

	if(NULL == L)
		return;

	list_insert(L, 10, 0);
	list_insert(L, 20, 0);
	list_insert(L, 30, 0);
	list_insert(L, 40, 0);
	list_insert(L, 50, 0);
	list_insert(L, 60, 0);
	list_show(L);

	list_delete(L, 6);
	list_show(L);
	list_free(L);
}

void test_merge()
{

	sqlink L1, L2;

	L1 = list_create();
	if(NULL == L1)
		return;

	L2 = list_create();
	if(NULL == L2)
		return;

	list_insert(L1, 10, 0);
	list_insert(L1, 20, 0);
	list_insert(L1, 30, 0);
	list_insert(L1, 40, 0);
	list_insert(L1, 50, 0);
	list_insert(L1, 60, 0);
	list_show(L1);

	list_insert(L2, 10, 0);
	list_insert(L2, 70, 0);
	list_insert(L2, 30, 0);
	list_insert(L2, 80, 0);
	list_insert(L2, 50, 0);
	list_insert(L2, 90, 0);
	list_show(L2);
	
	list_merge(L1, L2);
	list_show(L1);

	list_free(L1);
	list_free(L2);
}

void test_purge()
{
	sqlink L;
	L = list_create();

	if(NULL == L)
		return;

	list_insert(L, 10, 0);
	list_insert(L, 20, 0);
	list_insert(L, 20, 0);
	list_insert(L, 40, 0);
	list_insert(L, 20, 0);
	list_insert(L, 40, 0);
	list_show(L);

	list_purge(L);
	list_show(L);

	list_free(L);
}

sqlist.h

#if 0
typedef int data_t;//
#define N 128
struct sqlist_t
{
	data_t data[N];
	int last;
};

typedef struct sqlist_t sqlist;//sqlist L;struct sqlist_t sqlist L;
typedef struct sqlist_t * sqlink;//struct sqlist_t *p;sqlink p;
#endif

typedef int data_t;
#define N 128
typedef struct
{
	data_t data[N];
	int last;
}sqlist,* sqlink;

sqlink list_create();
int list_clear(sqlink L);
int list_free(sqlink L);
int list_empty(sqlink L);
int list_length(sqlink L);
int list_lacate(sqlink L, data_t value);
int list_insert(sqlink L, data_t value, int position);
int list_show(sqlink L);
int list_delete(sqlink L, int position);
int list_merge(sqlink L1, sqlink L2);
int list_purge(sqlink L);

sqlist.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlist.h"

sqlink list_create()
{
	//malloc
	sqlink L;
	L = malloc(sizeof(sqlist));
	if(NULL == L)
	{
		printf("malloc failed\n");
		return L;
	}

	//initialize
	memset(L, 0, sizeof(sqlist));
	L->last = -1;

	//return
	return L;
}
/* list_clear:clear list
 * para:list
 * @ret    0-success   -1-failed
 * */
int list_clear(sqlink L)
{
	if(NULL == L)
	{
		return -1;
	}

	memset(L, 0, sizeof(sqlist));
	L->last = -1;

	return 0;
}
int list_free(sqlink L)
{
	if(NULL == L)
	{
		return -1;
	}
	free(L);
	L = NULL;
	return 0;
}
/*
 * list_empty:Is list empty?
 * para L:list
 * @ret   1--empty  0--not empty 
 * */
int list_empty(sqlink L)
{
	if(L->last == -1)
	{
		return 1;
	}
	else
	{
		return 0;
	}
	
}
/*
 * list_length:Calculate the linear list lenght
 * para L:list
 * @ret -1--invalid list   Otherwise than,it is the actual length
 * */
int list_length(sqlink L)
{
	if(NULL == L)
	{
		return -1;
	}
	else
	{
		return (L->last+1);
	}
}
/* 
 * list_lacate:Positioning parameter position
 * para: list
 * @ret -1 not exsit    Otherwise than, it is the actual lacate
 * */
int list_lacate(sqlink L,data_t value)
{
	int i;
	for(i = 0; i <= L->last; i++)
	{
		if(L->data[i] == value)
		{
			return i;
		}
	}

	return -1;
}

int list_insert(sqlink L,data_t value,int position)
{
	int i;
	//full
	if(L->last == N-1)
	{
		printf("list is full\n");
		return -1;
	}

	//check para    0<=position<=last+1   [0, last+1]
	if(position < 0 || position > L->last+1)
	{
		printf("position is invalid\n");
		return -1;
	}

	//move
	for(i = L->last; i >= position; i--)
	{
		L->data[i+1] = L->data[i];
	}

	//updata
	L->data[position] = value;
	L->last++;
	return 0;
}

int list_show(sqlink L)
{
	int i;
	if(NULL == L)
	{
		return -1;
	}
	if(L->last == -1)
	{
		printf("list is empty\n");
	}
	for(i = 0; i <= L->last; i++)
	{
		printf("%d ", L->data[i]);
	}
	puts("");

	return 0;
}
int list_delete(sqlink L, int position)
{
	int i;
	if(L->last == -1)
	{
		printf("list is empty\n");
		return -1;
	}
	//position [0, last]
	if(position < 0 || position > L->last)
	{	
		printf("delete position is invalid\n");
		return -1;
	}
	//move [position+1, last]
	for(i = position + 1; i <= L->last; i++)
	{
		L->data[i-1] = L->data[i];
	}
	//updata
	L->last--;
	return 0;
}

int list_merge(sqlink L1, sqlink L2)
{
	int i = 0;
	int ret;
	while(i <= L2->last)
	{
		ret = list_lacate(L1, L2->data[i]);

		if(ret == -1)
		{
			if(list_insert(L1, L2->data[i], L1->last+1) == -1)
			{
				return -1;
			}
		}
		i++;
	}
	return 0;
}

int list_purge(sqlink L)
{
	int i = 1;
	int j;

	if(L->last == 0)
	{
		return 0;
	}
	while(i <= L->last)
	{
		j = i - 1;
		while(j >= 0)
		{
			if(L->data[i] == L->data[j])
			{
				list_delete(L, i);
				break;
			}
			else
			{
				j--;
			}
		}
		if(j < 0)
		{
			i++;
		}	
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值