1 线性表的定义
线性表 (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有且仅有一个直接前驱
2 操作线性表
1)第一步当然是创建一个链表
#include <stdio.h>
#include <malloc.h>
#define LIST_MAX_LENGTH 10
typedef struct SequentialList {
int actualLength;
int data[LIST_MAX_LENGTH];
} *SequentialListPtr;
//(别忘了头函数!)
2)然后就是把它打印出来
void outputList(SequentialListPtr paraList) {
for(int i = 0; i < paraList->actualLength; i ++) {
printf("%d ", paraList->data[i]);
}//打印单个元素
printf("\r\n");//换行
}
void OutputMemory(SequentialListPtr paraListPtr) {//打印链表的一些数据
printf("看一下各项数据的地址:\r\n");
printf("结构的地址: %ld\r\n", paraListPtr);
printf("存储大小的地址是: %ld\r\n", ¶ListPtr->actualLength);
printf("data的地址是: %ld\r\n", ¶ListPtr->data);
printf("data的首地址是: %ld\r\n", ¶ListPtr->data[0]);
printf("data的第二位地址是: %ld\r\n", ¶ListPtr->data[1]);
}
3)开始初始化链表
SequentialListPtr sequentialListInit(int paraData[], int paraLength) {
SequentialListPtr resultPtr = (SequentialListPtr)malloc(sizeof(struct SequentialList));
for (int i = 0; i < paraLength; i ++) {
resultPtr->data[i] = paraData[i];
}
resultPtr->actualLength = paraLength;
return resultPtr;
}
4)在这个链表里插入一个元素
void sequentialListInsert(SequentialListPtr paraListPtr, int paraPosition, int paraValue) {
// 第一步,检查空间是否足够
if (paraListPtr->actualLength >= LIST_MAX_LENGTH) {
printf("Cannot insert element: list full.\r\n");
return;
}//大了就装不下了
// 第二步,检查一下位置是否正确
if (paraPosition < 0) {
printf("Cannot insert element: negative position unsupported.");
return;
}
if (paraPosition > paraListPtr->actualLength) {
printf("Cannot insert element: the position %d is bigger than the list length %d.\r\n", paraPosition, paraListPtr->actualLength);
return;
}//位置不对插不进去
// 第三步,移动主要数据
for (int i = paraListPtr->actualLength; i > paraPosition; i --) {
paraListPtr->data[i] = paraListPtr->data[i - 1];
}//整体后移一位,腾个位置出来
// 第四步,开插!
paraListPtr->data[paraPosition] = paraValue;
// 第五步,更新一下长度
paraListPtr->actualLength ++;
}
5)插入测试一下看有没有问题
//随机测试
void sequentialInsertTest() {
int i;
int tempArray[5] = {3, 5, 2, 7, 4};
printf("---- sequentialInsertTest begins. ----\r\n");
// 初始化链表
SequentialListPtr tempList = sequentialListInit(tempArray, 5);
printf("After initialization, the list is: ");
outputList(tempList);
// 在0位置插入8
printf("Now insert to the first, the list is: ");
sequentialListInsert(tempList, 0, 8);
outputList(tempList);
// 在6位置插入9
printf("Now insert to the last, the list is: ");
sequentialListInsert(tempList, 6, 9);
outputList(tempList);
// 插几个不合法的数
printf("Now insert beyond the tail. \r\n");
sequentialListInsert(tempList, 77, 999);
sequentialListInsert(tempList, -9, 999);
printf("The list is:");
outputList(tempList);
// 首插演示
for (i = 0; i < 5; i ++) {
printf("Inserting %d.\r\n", (i + 10));
sequentialListInsert(tempList, 0, (i + 10));
outputList(tempList);
}
printf("---- 顺序插入测试结束 ----\r\n");
}
6)现在是删除元素的操作
int sequentialListDelete(SequentialListPtr paraListPtr, int paraPosition) {
// 第一步,检查位置是否合理
if (paraPosition < 0) {
printf("Invalid position: %d.\r\n", paraPosition);
return -1;
}
if (paraPosition >= paraListPtr->actualLength) {
printf("Cannot delete element: the position %d is beyond the list length %d.\r\n", paraPosition, paraListPtr->actualLength);
return -1;
}//不合理返回-1
// 第二步,移动这些数据
int resultValue = paraListPtr->data[paraPosition];
for (int i = paraPosition; i < paraListPtr->actualLength; i ++) {
paraListPtr->data[i] = paraListPtr->data[i + 1];
}//腾位置
// 第三步,更新长度
paraListPtr->actualLength --;
// 最后,返回值
return resultValue;
}
7)测试一下删除功能有没有问题
void sequentialDeleteTest() {
int tempArray[5] = {3, 5, 2, 7, 4};
printf("---- sequentialDeleteTest begins. ----\r\n");
// 初始化链表
SequentialListPtr tempList = sequentialListInit(tempArray, 5);
printf("After initialization, the list is: ");
outputList(tempList);
// 删除首位
printf("Now delete the first, the list is: ");
sequentialListDelete(tempList, 0);
outputList(tempList);
// 再删除末位
printf("Now delete the last, the list is: ");
sequentialListDelete(tempList, 3);
outputList(tempList);
// 然后一直删除第二位
printf("Now delete the second, the list is: ");
sequentialListDelete(tempList, 1);
outputList(tempList);
printf("Now delete the 5th, the list is: ");
sequentialListDelete(tempList, 5);
outputList(tempList);
//选一个不合法的位置删掉,和插入操作一样
printf("Now delete the (-6)th, the list is: ");
sequentialListDelete(tempList, -6);
outputList(tempList);
printf("---- 顺序删除测试结束 ----\r\n");
OutputMemory(tempList);
}
8)做一个返回指定元素位置的函数
int locateElement(SequentialListPtr paraListPtr, int paraValue) {
if (paraValue < 0 ||paraValue >paraListPtr->actualLength) {
printf("Wrong input! Please re-enter it!");
return -1;
}//不合法直接pass
for (int i = 0; i < paraListPtr->actualLength; i ++) {
if (paraListPtr->data[i] == paraValue)
{
return i;
}//对了直接返回i
}
}
9)再搞一个返回第n个位置的值的函数
int getElement(SequentialListPtr paraListPtr, int paraPosition) {
// 检查输入是否合法
if (paraPosition < 0 || paraPosition >= paraListPtr->actualLength) {
printf("Invalid position: %d.\r\n", paraPosition);
return -1;}
// 合法就返回值
return paraListPtr->data[paraPosition-1];
}
10)最后清空顺序表
void clearList(SequentialListPtr paraListPtr) {
paraListPtr->actualLength = 0;
}
函数的实现
void main() {
sequentialInsertTest();
sequentialDeleteTest();
}
运行结果
不才学艺不精,如有问题欢迎指正。
最后,再次感谢各位的阅读。