数据结构线性表-C语言实现

本文详细介绍了如何使用C语言实现一个顺序链表,包括初始化、插入、删除、查找元素以及内存地址的输出,展示了链表在数据结构中的应用和其优缺点。
摘要由CSDN通过智能技术生成

代码如下

#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", &paraListPtr->actualLength);
	printf("The address of data: %ld\r\n", &paraListPtr->data);
	printf("The address of actual data: %ld\r\n", &paraListPtr->data[0]);
	printf("The address of second data: %ld\r\n", &paraListPtr->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))。

适用于频繁插入、删除。

| 画图分析 |

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值