代码如下
#include <stdio.h>
#include <malloc.h>
#define LIST_MAX_LENGTH 10
//整数的线性列表-关键是数据
typedef struct SequentialList //定义结构体链表
{
int actualLength;
int data[LIST_MAX_LENGTH];//设置MAX值
} *SequentialListPtr;
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("The address of the structure: %ld\r\n", paraListPtr);
printf("The address of actualLength: %ld\r\n", ¶ListPtr->actualLength);
printf("The address of data: %ld\r\n", ¶ListPtr->data);
printf("The address of actual data: %ld\r\n", ¶ListPtr->data[0]);
printf("The address of second data: %ld\r\n", ¶ListPtr->data[1]);
}
//初始化顺序列表。此函数没有错误检查。
//paraListPtr指向列表的指针。它必须是一个指针才能更改列表。
//paraValues存储所有元素的int数组。
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;
}
//将元素插入顺序线性列表中。
//paraListPtr---指向列表的指针。它必须是一个指针才能更改列表
//paraPosition---位置,例如0代表在第一个位置插入
//paraValue---要插入的值
void sequentialListInsert(SequentialListPtr paraListPtr, int paraPosition, int paraValue)//链表插入位置元素
{
//空间检查
if (paraListPtr->actualLength >= LIST_MAX_LENGTH) {
printf("Cannot insert element: list full.\r\n");
return;
}//长度已达到MAX值-不能继续插入
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++;//更新链表长度
}
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);
printf("Now insert to the first,the list is: ");//插到头
sequentialListInsert(tempList, 0, 8);
OutPutList(tempList);
printf("Now insert to the last,the list is: ");//插到最后
sequentialListInsert(tempList, 6, 9);
printf("The list is: ");
OutPutList(tempList);
printf("Now insert beyond the tail. \r\n");//插到结尾之前
sequentialListInsert(tempList,8,9);
printf("The list is: ");
OutPutList(tempList);
for (int i = 0; i < 5; i++) {
printf("Inserting %d.\r\n", (i + 10));
sequentialListInsert(tempList, 0, (i + 10));
OutPutList(tempList);
}
printf("----- sequentialInsertTest ends. ----\r\n");
}
//从连续线性列表中删除元素
//paraListPtr指向列表的指针。它必须是一个指针才能更改列表
//paraPosition位置,例如0代表在第一个位置插入
//return删除的值
int sequentialListDelete(SequentialListPtr paraListPtr,int position)//链表删除位置元素
{
//删除位置合理化检查
if (position < 0) {
printf("Invalid position: %d.\r\n", position);
return -1;
}
if (position >= paraListPtr->actualLength) {
printf("Can't delete element: teh position %d is beyond the list length %d.\r\n",position,paraListPtr->actualLength);
return -1;
}
int resultValue = paraListPtr->data[position];
for (int i = position; i < paraListPtr->actualLength; i++) {
paraListPtr->data[i] = paraListPtr->data[i + 1];
}//将链表数据前移一位
paraListPtr->actualLength--;
return resultValue;
}
void sequentialDeleteTest()//链表删除测试
{
int tempArray[5] = { 3,5,2,7,4 };
printf("\n----- sequentialDeletTest 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: ");//删第-6个
sequentialListDelete(tempList, -6);
OutPutList(tempList);
printf("---- sequentialDeleteTest ends. ----\r\n");
OutPutMemory(tempList);//输出链表内存
}
//在列表中找到一个元素。
//paraListPtr指向列表的指针。
//paraValue指示值。
//return值的位置,或者 - 1表示不存在
int locateElement(SequentialListPtr paraListPtr, int paraValue)//查找value值在链表中位置
{
for (int i = 0; i < paraListPtr->actualLength; i++) {
if (paraListPtr->data[i] == paraValue) {
return i;
}
}
return -1;
}
//在列表中获取一个元素。
//paraListPtr指向列表的指针。
//paraPosition给定的位置。
//return值的位置,或者 - 1表示不存在
int getElement(SequentialListPtr paraListPtr, int position)//查找链表中位置元素的值
{
//位置合理化检查
if (position < 0) {
printf("Invalid position: %d.\r\n", position);
return -1;
}
if (position >= paraListPtr->actualLength) {
printf("Can't get element:the position %d is beyond the list length %d.\r\n", position, paraListPtr->actualLength);
return -1;
}
return paraListPtr->data[position];
}
void changeElement(SequentialListPtr paraListPtr, int position, int value)//改变链表中位置元素的值
{
//位置合理化检查
if (position < 0) {
printf("Invalid position: %d.\r\n", position);
return;
}
if (position >= paraListPtr->actualLength) {
printf("Can't change element:the position %d is beyond the list length %d.\r\n", position, paraListPtr->actualLength);
return;
}
for (int i = 0; i < paraListPtr->actualLength; i++) {
if (i == position) {
paraListPtr->data[i] = value;
return;
}
}
}
//清除列表中的元素
//paraListPtr是指向列表的指针
//returnd的是值的位置,或者 - 1表示不存在
void clearList(SequentialListPtr paraListPtr)//清空链表---将长度变为0
{
paraListPtr->actualLength = 0;
}
void main()
{
sequentialInsertTest();
sequentialDeleteTest();
}
运行结果如下
代码功能:链表的增删改查,还有查找目标值在链表中位置,链表内存检查的输出,链表清空等。
心得体会:通过敲这整个代码,我对链表的理解更深刻,链表的链式结构储存数据,具有的功能也是通过一个连一个的链式结构进行遍历来实现。
| 链式存储结构 |
优点:插入、删除不需要移动数据,只需要移动指针,效率高(时间复杂度为O(1));
缺点:是存取时需要遍历所有数据,效率低(时间复杂度为O(n))。
适用于频繁插入、删除。
| 画图分析 |