2.5 线性表的建表

本文介绍了顺序表和链表的建表方法。对于顺序表,当数组长度超过预设的最大长度时,建表失败。通过循环输入数组元素完成建表。链表部分,讲解了带头结点的单链表建表,包括尾插法和头插法,两种方法分别按照输入顺序和反向构建链表。

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

1. 顺序表建表

        策略: 给定数组arr和数组长度length, 若length长度大于MAX_SIZE, 则建表失败. 进行length次的循环, 每次循环输入一个数组元素的值, 循环结束则建表结束. 

#include <iostream>

/// <summary>
/// 数组最大长度
/// </summary>
const int MAX_SIZE = 10;

/// <summary>
/// 顺序表建表
/// </summary>
/// <param name="arr">数组</param>
/// <param name="length">要创建的数组的长度</param>
/// <returns></returns>
int createList(int* arr, int& length) {
	printf("请输入数组长度: \n");
	scanf_s("%d", &length);
	if (length > MAX_SIZE) {
		return 0;
	}
	for (int i = 0; i < length; i++)	//i取值范围: 0~length - 1
	{
		printf("请输入数据: \n");
		scanf_s("%d", &arr[i]);
	}
	return 1;
}

int main()
{
	int arr[MAX_SIZE];
	int length;
	int result = createList(arr, length);
	if (result == 1) {
		printf("建表成功, 数组元素为: \n");
		for (int i = 0; i < length; i++)
		{
			printf("%d ", arr[i]);
		}
	}
}

代码1: 顺序表建表

2. 链表建表

        这里介绍的是带头结点的单链表的建表方法. 双链表, 循环单链表, 循环双链表等建表方法不做介绍, 因为它们都是由这个基础算法推演而来, 只需要做些改动即可. 

1. 尾插法建表

 图1. 尾插法建立单链表

        策略: 在链表末尾插入元素, 因此需要尾指针r, 最初建表时只有一个头结点, 因此r = head; 用p记录当前要插入的结点. 输入链表长度n, 进行n次循环插入, 每次插入时, 输入p结点的data值, 然后将p结点连接至尾结点的后面, 即 r -> next = p; 然后再更新 r 指针指向最新的尾结点, 即 r = p; 循环结束则建表结束. 

#include <iostream>

//C++用new创建对象时返回的是一个对象指针,object指向一个ClassName的对象,
//C++分配给object的仅仅是存放指针值的空间。
//而且,用new 动态创建的对象必须用delete来撤销该对象。
//只有delete对象才会调用其析构函数。

/// <summary>
/// 链表结点结构体定义
/// </summary>
typedef struct LNode {
	int data;
	struct LNode* next;
}LNode;

/// <summary>
/// 尾插法建含头结点的单链表
/// </summary>
/// <param name="head">头结点</param>
void createLinkListR(LNode*& head) {
	head = (LNode*)malloc(sizeof(LNode));	//为头结点分配空间
	head->data = NULL;
	head->next = NULL;			//建立一个带头结点的链表
	LNode* p = NULL;			//当前插入的结点
	LNode* r = head;			//r为指向尾部结点的指针
	int n;						//n为表中数据结点个数
	printf("请输入链表长度: \n");
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++)
	{
		p = (LNode*)malloc(sizeof(LNode));	//为结点分配存储空间
		p->next = NULL;
		printf("请输入结点的值: \n");
		scanf_s("%d", &(p->data));

		//尾插法关键代码
		//p->next = r->next;	//本句可省略, 因为r指向尾结点, r->next == NULL恒成立
		r->next = p;
		r = p;
	}
}

int main()
{
	LNode* H;
	createLinkListR(H);

	LNode* p = H;

	while (p != NULL)		//注意这里是p!=NULL而不是p->next!=NULL	
	{
		if (p->data != 0) {	//头结点的判断放在循环里面, 放在循环外面则循环一次也不会执行
			printf("链表元素的值:%d\n", p->data);
		}
		p = p->next;
	}
}

代码2: 尾插法建立单链表

        尾插法有一个指向尾部结点的指针, 尾插法表中数据与输入的数据顺序相同

2. 头插法建表

图2. 头插法建立单链表

        策略: 在链表的头部插入元素, 这里的头部指的是头结点后面的位置. 由于可以根据头结点指针head获取要插入的位置, 因此不需要额外的指针, 只需要当前要插入的结点的指针p即可. 输入链表长度n, 进行n次循环插入. 每次插入时, 输入p的data值, p先指向头结点的后面一个结点, 即p->next = head->next; 然后头结点指针再指向p, 即head->next = p; 循环结束则建表结束. 

#include <iostream>

/// <summary>
/// 链表结点结构体定义
/// </summary>
typedef struct LNode {
	int data;
	struct LNode* next;
}LNode;

/// <summary>
/// 头插法建含头结点的单链表
/// </summary>
/// <param name="head">头结点</param>
void createLinkListH(LNode*& head) {
	head = (LNode*)malloc(sizeof(LNode));	//为头结点分配空间
	head->data = NULL;
	head->next = NULL;			//建立一个带头结点的链表
	LNode* p = NULL;			//当前插入的结点
	int n;						//n为表中数据结点个数
	printf("请输入链表长度: \n");
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++)
	{
		p = (LNode*)malloc(sizeof(LNode));	//为结点分配存储空间
		p->next = NULL;
		printf("请输入结点的值: \n");
		scanf_s("%d", &(p->data));

		//头插法关键代码
		p->next = head->next;
		head->next = p;
	}
}

int main()
{
	LNode* H;
	createLinkListH(H);

	LNode* p = H;

	while (p != NULL)		//注意这里是p!=NULL而不是p->next!=NULL	
	{
		if (p->data != 0) {	//头结点的判断放在循环里面, 放在循环外面则循环一次也不会执行
			printf("链表元素的值:%d\n", p->data);
		}
		p = p->next;
	}
}

代码3: 头插法建立单链表

        头插法只需要head指针和结点指针p即可完成建表操作, 头插法表中数据与输入的数据顺序相反

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值