线性表及其相关操作

本文深入探讨线性表这一基本数据结构的概念、特点及应用。解析线性表中数据元素间的一对一关系,介绍结点定义与具体操作代码,包括初始化、插入、删除等关键函数,并展示代码运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、定义

      线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear list)数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。

      线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点)。

      线性表(linear list)数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。数据元素是一个抽象的符号,其具体含义在不同的情况下一般不同。

      在稍复杂的线性表中,一个数据元素可由多个数据项(item)组成,此种情况下常把数据元素称为记录(record),含有大量记录的线性表又称文件(file)

      线性表中的个数n定义为线性表的长度,n=0时称为空表。在非空表中每个数据元素都有一个确定的位置,如用ai表示数据元素,则i称为数据元素ai在线性表中的位序。

      线性表的相邻元素之间存在着序偶关系。如用(a1,…,ai-1,ai,ai+1,…,an)表示一个顺序表,则表中ai-1领先于ai,ai领先于ai+1,称ai-1是ai的直接前驱元素,ai+1是ai的直接后继元素。当i=1,2,…,n-1时,ai有且仅有一个直接后继,当i=2,3,…,n时,ai有且仅有一个直接前驱。

二、结点定义

#define LIST_INIT_SIZE     100
#define LISTINCREMENT  10
typedef int ElemType;
typedef ElemType Status;

typedef struct {
	ElemType *elem;
	int length;    //当前已用
	int listsize;    //已分配
}SqList;

三、具体操作的相关代码

1.SqList.h

#define LIST_INIT_SIZE     100
#define LISTINCREMENT  10
typedef int ElemType;
typedef ElemType Status;

typedef struct {
	ElemType *elem;
	int length;    //当前已用
	int listsize;    //已分配
}SqList;

bool InitList_Sq(SqList &L);
bool ListInsert_Sq(SqList &L, int i, ElemType e);
bool ListDelete_Sq(SqList &L, int i, ElemType &e);
int ListLength_Sq(SqList &L);


int greater(ElemType argv1, ElemType argv2);
int less(ElemType argv1, ElemType argv2);
int equal(ElemType argv1, ElemType argv2);

void MergeList_Sq(SqList La, SqList Lb, SqList &Lc);   //归并两个线性表中的元素,使其有序排列
int LocateElem_Sq( SqList &L, ElemType e, Status(*compare)(ElemType, ElemType) );
void Show_Sq(SqList &L);

2.SqList.cpp

#include"SqList.h"
#include<stdio.h>
#include<stdlib.h>

bool InitList_Sq(SqList &L)
{
	L.elem = (ElemType *)malloc(sizeof(ElemType)*LIST_INIT_SIZE);
	if (!L.elem)
	{
		return false;
	}
	L.length = 0;
	L.listsize = LIST_INIT_SIZE;
	return true;
}

bool ListInsert_Sq(SqList &L, int i, ElemType e)
{
	if (i<1 || i>L.length + 1)    //5 2 7 4 6 3
	{
		return false;
	}
	if (L.length >= L.listsize)
	{
		ElemType *newbase = (ElemType*)realloc( L.elem, L.listsize + LISTINCREMENT*sizeof(ElemType) );
		if (!newbase)
		{
			return false;
		}
		L.elem = newbase;
		L.listsize += LISTINCREMENT;
	}
	ElemType*q = &(L.elem[i - 1]);
	for (ElemType *p = &(L.elem[L.length - 1]); p >= q; --p)
	{
		*(p + 1) = *p;  //前赋后
	}

	*q = e;
	++L.length;
	return true;
}

bool ListDelete_Sq(SqList &L, int i, ElemType &e)
{
	if (i<1 || (i>L.length))
	{
		return false;
	}
	
	ElemType* p = &(L.elem[i - 1]);    //5 2 7 4 6 3
	e = *p;
	ElemType* q = L.elem + L.length - 1;   //末尾
	for (++p; p <= q; ++p)      //p指向第二个元素
	{
		*(p - 1) = *p;    //后赋前
	}

	--L.length;
	return true;
}

int greater(ElemType argv1, ElemType argv2)  //大于
{
	return argv1 > argv2;
}

int less(ElemType argv1, ElemType argv2)    //小于
{
	return argv1 < argv2;
}

int equal(ElemType argv1, ElemType argv2)   //等于
{
	return argv1 == argv2;
}

int ListLength_Sq(SqList &L)
{
	return L.length;
}

void MergeList_Sq(SqList La, SqList Lb, SqList &Lc)
{
	ElemType* pa = La.elem;
	ElemType* pb = Lb.elem;

	Lc.listsize = Lc.length = La.length + Lb.length;
	ElemType* pc = Lc.elem = (ElemType*)malloc( Lc.listsize*sizeof(ElemType) );
	if (!Lc.elem)
	{
		return;
	}
	
	ElemType* pa_last = La.elem + La.length - 1;
	ElemType* pb_last = Lb.elem + Lb.length - 1;

	while (pa <= pa_last && pb <= pb_last)   //相同长度进行归并
	{
		if (*pa < *pb)
		{
			*pc++ = *pa++;
		}
		else if (*pa > *pb)
		{
			*pc++ = *pb++;
		}
		else
		{
			*pc++ = *pa++;
			pb++;
			--Lc.length;
		}
	}

	while (pa <= pa_last)
	{
		*pc++ = *pa++;
	}
	while (pb <= pb_last)
	{
		*pc++ = *pb++;
	}

}

int LocateElem_Sq(SqList &L, ElemType e, Status(*compare)(ElemType, ElemType))   
//在线性表L中查找第1个值与e满足compare()的元素的位序
{
	int i = 1;
	ElemType* p = L.elem;
	while ( i<=L.length && !(*compare)(*p++, e) )
	{
		++i;
	}
	if (i <= L.length)
	{
		return i;
	}
	else
	{
		return 0;
	}
}

void Show_Sq(SqList &L)
{
	if (NULL == L.elem)
	{
		return;
	}
	for (int i = 0; i < L.length; i++)
	{
		printf("%d ", L.elem[i]);
	}
	printf("\n");
}

3.main.cpp

#include<stdio.h>
#include"SqList.h"
#include<stdlib.h>
#include<time.h>

int main()
{
	SqList MySqList;
	ElemType e;

	InitList_Sq(MySqList);

	for (int i = 1; i <= 10; i++)
	{
		ListInsert_Sq(MySqList, i, i);
	}
	Show_Sq(MySqList);
	
	ListDelete_Sq(MySqList, 10, e);
	printf("%d\n", e);

	Show_Sq(MySqList);

	int pos = LocateElem_Sq(MySqList, 5, equal);
	printf("%d\n", pos);

	SqList La;
	InitList_Sq(La);
	SqList Lb;
	InitList_Sq(Lb);
	SqList Lc;
	InitList_Sq(Lc);

	//srand( (unsigned)time(NULL) );
	for (int i = 1; i <= 5; i++)
	{
		int a = i + 2;
		ListInsert_Sq(La, i,a);
	}
	Show_Sq(La);

	for (int i = 1; i <= 5; i++)
	{
		int b = i + 4;
		ListInsert_Sq(Lb, i, b);
	}
	Show_Sq(Lb);

	MergeList_Sq(La, Lb, Lc);
	Show_Sq(Lc);
    
    //此处缺少摧毁函数,有意者自行添加
}

四、代码运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值