9 线性表-实现

文章介绍了线性表的顺序存储结构,包括建立、置空、判断是否为空、求表长、取元素、定位、插入和删除等基本运算。同时,讨论了顺序存储的优缺点,如存储密度高、随机存取,以及插入删除时可能需要大量元素移动的问题。提供了C语言的代码实现,包括list_create、list_insert、list_delete等函数,以及测试示例。
摘要由CSDN通过智能技术生成

线性表的基本运算

设线性表L=(a0,a1…,a(n-1)),对L的基本运算有:
(1)建立一个空表:list_create(L);
(2)置空表:list_clear(L);
(3)判断表是否为空:list_empty(L)。若表为空,返回值为1,否则返回0
(4)求表长:length(L)
(5)取表中某个元素:GetList(L, i),即ai。要求0<=i<=length(L)-1
(6)定位运算:Locate(L, x)。确定元素x在表L中的位置(序号)
(7)插入:
Insert(L,x,i)。将元素x插入到表L中第i个元素ai之前,且表长+1。
插入前: (a0,a1,—,ai-1,ai,ai+1-------,an-1) 0≤i≤n,i=n时,x插入表尾
插入后: (a0,a1,—,ai-1, x, ai,ai+1-------,an-1)
算法思路:若表存在空闲空间,且参数i满足:0≤i≤L->last+1,则可进行正常插入。
插入前,将表中(L->data[L->last]~L->data[i])部分顺序下移一个位置,然后将x插入L->data[i]处即可。算法对应的表结构。
在这里插入图片描述

(8)删除:Delete(L,i)。删除表L中第i个元素ai,且表长减1, 要求0≤i≤n-1。
删除前: (a0,a1,—,ai-1,ai,ai+1-------,an-1)
删除后: (a0,a1,—,ai-1,ai+1-------,an)在这里插入图片描述

线性表的顺序存储缺点

线性表的顺序存储结构有存储密度高及能够随机存取等优点,但存在以下不足:
(1)要求系统提供一片较大的连续存储空间
(2)插入、删除等运算耗时,且存在元素在存储器中成片移动的现象;

代码实现

sqlist.h

typedef int data_t; // typedef后面跟已有类型
#define N 128       // 后面跟的是宏
 
typedef struct {
	data_t data[N];
	int last;
}sqlist, *sqlink;
 
// 使用sqlink时,不需要加*,因为在typedef里面struct sqlist_t *是一体的,被sqlink所代替
sqlink list_create();     // 函数list_create的返回值是一个指针,指向结构体类型
int list_clear(sqlink L);
int list_delete(sqlink L);
int list_empty(sqlink L);
int list_length(sqlink L);
int list_locate(sqlink L, data_t value);
int list_insert(sqlink L, data_t value, int pos);
int list_show(sqlink L);

sqlist.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sqlist.h"
 
// 申请内存  初始化变量  返回指针
sqlink list_create() {
	// 申请内存
	sqlink L;
	L =(sqlink)malloc(sizeof(sqlist)); // L接受的是所申请内存的起始地址,(sqlink)是强制类型转换,转换为结构体指针
	if (L == NULL) {
		printf("list malloc failed\n");
		return L;
	}
 
	// 初始化变量
	memset(L, 0, sizeof(sqlist)); // 从L开始的sizeof(sqlist)个字节全部用0填充
	L->last = -1; 
 
	//return
	return L;
}
 
/*
 * @ret   0-success   -1-failed
*/
int list_clear(sqlink L) {  // 清除表的内容,表还在
	if (L == NULL)
		return -1; 
 
	memset(L, 0, sizeof(sqlist));
	L->last = -1;
 
	return 0;
}
 
int list_free(sqlink L){   // 表不在了
	if (L == NULL) 
		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;
}
 
int list_length(sqlink L) {
	if (L == NULL) 
		return -1;
	return (L->last+1);
}
 
int list_locate(sqlink L, data_t value) {
 
	return 0;
}
 
int list_insert(sqlink L, data_t value, int pos) {
	int i;
 
	//full,last是索引值,从0开始数
	if (L->last == N-1) {
		printf("list is full\n");
		return -1;
	}
 
	//check para    0<=pos<=Last+1   [0, last+1],last+1表示往表末插入一个数
	if (pos < 0 || pos > L->last+1) {
		printf("Pos is invalid\n");
		return -1;
	}
 
	//move,从后往前移,i=pos时,循环将pos对应的位置空了出来
	for (i = L->last; i >= pos; i--) {
		L->data[i+1] = L->data[i];
	}
 
	//update value last
	L->data[pos] = value;
	L->last++;
 
	return 0;
}
 
int list_show(sqlink L) {
	int i;
 
	if (L == NULL) 
		return -1;
	if (L->last == -1)
		printf("list is empty\n");
 
	for (i = 0; i <= L->last; i++) {
		printf("%d ", L->data[i]);
	}
	puts("");   // puts默认加换行符,这里的作用就是换行
 
	return 0;
}

test.c

#include <stdio.h>
#include "sqlist.h"
 
void test_insert();
 
int main(int argc, const char *argv[])
{
	test_insert();
 
	return 0;
}
 
void test_insert() {
	sqlink L;
	
	L = list_create();
	if (L == NULL) 
		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, list_length(L));
	list_insert(L, 100, -1000);
	list_show(L);
	list_free(L);
}

线性表(顺序表)复杂操作的实现
删除

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

查找

/*
 * @ret  -1--not exist   pos
 * */
int list_locate(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_merge(sqlink L1, sqlink L2) {
	int i = 0;
	int ret;
 
	while (i <= L2->last){
		ret = list_locate(L1, L2->data[i]);
		if (ret == -1) {
			if (list_insert(L1, L2->data[i], L1->last+1) == -1) 
				return -1;
		}
 
		i++;
	}
	return 0;
}

清除表中重复元素

// 从表的第二个位置(索引1的位置)开始向后遍历,每遍历到一个元素,就向前查找是否有重复元素,若有,删
// 除重复元素中相对靠后的那个,这样复杂度低一些
int list_purge(sqlink L) {
	int i;
	int j;
 
	if (L->last == 0) // 最后一个元素的索引是0,说明只有一个元素
		return 0;
 
	i = 1;     // 从索引1开始
	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、付费专栏及课程。

余额充值