线性表

191 阅读5分钟

逻辑结构

线性表

线性表定义

线性表是具有n个相同数据类型的数据元素的有限序列(n>=0)。n是表长,n=0时,线性表为空表。用L命名线性表,则可表示为L=(a1,a2,...,ai,ai+1,...an).

线性表是一种逻辑结构,表示元素之间一对一的相邻关系。顺序表和链表是指存储结构,两者属于不同层面的概念。

线性表的特点

  • 表中元素的个数有限。
  • 表中元素具有逻辑上的顺序性,在序列中各元素排列有其先后次序,即除了表头元素外,每个元素有且仅有一个直接前驱,除了表尾元素外,每个元素有且仅有一个直接后继
  • 表中元素都是数据元素,每个元素都是单个元素。
  • 表中元素的数据类型都相同,即每个元素占有相同大小的存储空间。
  • 表中元素具有抽象性,即仅讨论元素间的逻辑关系,而不考虑元素究竟表示什么内容。

线性表的基本操作

  • InitList(*L):初始化表。构造一个空的线性表。
  • ListInsert(*L,i,e):插入操作。在表L中第i个位置插入指定元素e。
  • ListDelete(*L,i,*e):删除操作,删除表L中第i个位置的元素,并用e返回删除元素的值。
  • LocateElem(L,e):按值查找元素并返回该元素的索引
  • GetElem(L,i):按索引查找元素并返回该元素的值
  • Length(L):求表长,返回线性表L的长度,即L中数据元素的个数。
  • PrintList(L):打印线性表。
  • Empty(L):判断线性表是否为空。
  • DestroyList(*L):销毁线性表并释放其内存。

存储结构

顺序表

顺序表的定义

线性表的顺序存储称为顺序表。它是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。

顺序表的特点

  • 增删慢,查询快
    • 增删平均时间复杂度O(n)
    • 查询时间复杂度
      • 按值查询平均时间复杂度O(n)
      • 按索引查询时间复杂度O(1)
  • 存储密度高,每个结点只存储数据元素
  • 逻辑上相邻的元素在物理位置上也相邻

按最好情况、最坏情况、平均情况分别分析

顺序表的实现

// Sequential storage of linear table 
// Static allocation of sequence table
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 5
// construct a sequence stable that can hold up to 5 elements;
typedef struct SeqList {
	int data[MAXSIZE];
	int length;
}SeqList; 

/* 
purpose: initialize sequence table.   
operation result: initialize sequence table.
*/
int SeqListInit(SeqList *pSeqList, int length){
	printf("Please enter the elements of the sequence table in order: ");
	for(int i = 1;i <= length;i++){
    	scanf("%d",&pSeqList->data[i-1]);
	}
	pSeqList->length = length;
	return 1;  // successful initialization returns 1. 
}
/*
purpose: insert elements. 
initial conditions: Sequence table L already exists, 1 <= L <= SeqListlength + 1.
operation result: Insert the given element e at the i-th position in table L, plus 1 for the length.
*/
int SeqListInsert(SeqList *pSeqList, int i, int e) {
	if(i < 1 || i > pSeqList->length + 1 || pSeqList->length == MAXSIZE)
	    return 0; // Inserted in wrong position, return 0.
	for(int k = pSeqList->length;k >= i;k--) {
		pSeqList->data[k] = pSeqList->data[k-1];
	}
	pSeqList->length++; 
	pSeqList->data[i-1] = e;
	return 1;
}
/*
purpose: delete elements. 
initial conditions: Sequence table L already exists, 1 <= L <= SeqListlength.
operation result: delete the element at the i-th position in table L, return it with e.
*/
int SeqListDelete(SeqList *pSeqList, int i, int *e) {
	if(i < 1 || i > pSeqList->length)
	    return 0; // delete in wrong position, return 0.
	*e = pSeqList->data[i-1];
	for(int k = i + 1; k <= pSeqList->length;k++) {
	    pSeqList->data[k-2] = pSeqList->data[k-1];
	} 
	pSeqList->length--;
	return 1;
} 
/*
purpose: return the length of the sequence table L.
intial conditions: Sequence table already exists.
opration result: return the length of sequence table L.
*/
int SeqListLength(SeqList *pSeqList) {
	return pSeqList->length;
}

/*
purpose: reset sequence table to empty table.
initial conditions: Sequence table already exists.
operation result: sequence table becomes an empty table.
*/
int SeqListClear(SeqList *pSeqList) {
	pSeqList->length = 0;
	return 1;
}
/*
purpose: judgment whether the sequence table is empty.
initial conditions: Sequence table already exists.
operation result: is empty return 1,not empty return 0;
*/
int SeqListEmpty(SeqList *pSeqList) {
	if(pSeqList->length == 0)
	    return 1;
	else return 0;
}
/*
purpose: return the position of the first element equal to the given element e.
initial conditions: Sequence table already exists.
operation result: return the position of the first element equal to the given element e.
*/ 
int LocateElem(SeqList *pSeqList, int e) {
	for(int i = 1;i <= pSeqList->length;i++) {
		if(pSeqList->data[i-1] == e)
		    return i;	
	}
	return -1;
}
/*
purpose: Get the value of the i-th element in the sequence table L.
intial conditions: Sequence table already exists.
operation result: return the value of the i-th element in the sequence table L.
*/
int GetElem(SeqList *pSeqList, int i) {
	if(i < 1 || i > pSeqList->length) return -1;
	else return pSeqList->data[i-1];
} 
/*
purpose: Print the elements in the sequence table
intial conditions: Sequence table already exists.
operation result: Print the elements in the sequence table.
*/
int PrintSeqList(SeqList *pSeqList) {
	printf("The elements of the sequence table in order are: ");
	for(int i = 1;i <= pSeqList->length;i++) {
		printf("%d  ",pSeqList->data[i-1]);
	}
	printf("\n");
	return 1;
}
int main(void) {
	SeqList L;
	int n;
	int j, m, p;
	printf("The length of the sequence table is: ");
	scanf("%d",&n);
	SeqListInit(&L, n);  // initialize a sequence table of length n.
	PrintSeqList(&L);
	SeqListInsert(&L, 3, 1);  // Insert an element at the third element position
	PrintSeqList(&L);
	SeqListDelete(&L, 3, &j); // delete an element at the third element position, and return the deleted value with j.
	PrintSeqList(&L);
	printf("The value of the deleted element is: %d\n", j);
	printf("Please enter the value you want to find: ");
	scanf("%d",&m);
	int position = LocateElem(&L, m);
	printf("The position of the element with value m is: %d\n",position);
	printf("Please enter the position of the element: ");
	scanf("%d",&p);
	int x = GetElem(&L, p);
	printf("The value of the %d position is: %x\n", p, x);
	SeqListClear(&L);
	printf("The length of the sequence table is: ");
	scanf("%d",&n);
	SeqListInit(&L, n);  // initialize a sequence table of length n.
	PrintSeqList(&L);
	int length = SeqListLength(&L);
	printf("The length of the SeqList is %d\n", length);
	return 0;
}

链表

单链表

单链表的定义