链表(二)

本文主要为mooc课程上北京理工大学C语言程序设计相关知识点的笔记与整理。

原课程地址:https://www.icourse163.org/learn/BIT-46004?tid=1450371454#/learn/content?type=detail&id=1214719596&cid=1218680522&replay=true

关于指针数组与数组指针的说明:https://www.cnblogs.com/mq0036/p/3382732.html

关于运算符优先级的说明:http://c.biancheng.net/view/161.html

1 typedef自定义类型

之前的内容中,结构和联合可以定义全新的自定义类型,而typedef则不产生全新的自定义类型,它是来说明一个数据类型,替代已有的数据类型。例如,我们可以使用一个有意义的名字,来替代已有的类型,提高程序的可读性;可以给一个复杂的数据类型起一个简单的名字,提高程序的应用性;也可以定义一个其他语言中的关键字来说明c语言的数据类型,提高程序的可移植性。

可以利用typedef来定义c语言中没有的数据类型

没有typedef ,OLD是一个结构体变量;有typedef,OLD是一个结构体类型,即DATA的别名。

2 枚举类型

系统会自动给数据列表中的数据从0开始赋值。

大括号中的值作为常量不可以被赋值,但可以被直接引用。

通过枚举类型可以定义一个取值有限的变量;取值是通过常量来进行描述的。

3 链表的概念

动态数据类型代表——链表

 

顺序存取单元是一次性分配,所以要按最大需要的空间来分配存储空间,可能存在空间分配的效率问题。

定义结点最重要是要在其指针域定义一个指向该种结构的指针。

4 链表的基本操作

如何开辟存储空间:

在内存分配与释放的过程中要求malloc与free配对使用。若未使用free()的话,会导致malloc分配的内存空间泄露。

表头结点不存储基本信息。p指向表头结点的首地址,而表头指针也需要指向表头结点的首地址,等效于将p赋给head。

 

表头结点在环链表中可以提示当前访问的结点是第几个数据结点。

相关知识点代码实现如下:

#include<stdio.h>
#include<stdlib.h>

struct node
{
	char name[20], address[20], phone[15];
	struct node* link;
};
typedef struct node NODE;

main()
{
	int len;
	NODE* head;
	NODE* p;
	p = (NODE*)malloc(sizeof(NODE));//开辟新存储区,申请表头结点
	p->link = NULL;
	head = p;//表头指针指向表头结点

	int create(NODE* head,int n);//创建链表
	int length(NODE * head);//求链表长度
	int insert_node(NODE * head, NODE * p, int i);//在第i个数据结点之后插入新结点
	int output(NODE * head);//输出链表内容
	int delete_node(NODE * head, int i);//删除第i个结点

	create(head, 3);//创建一个有三个数据结点的链表
	len = length(head);
	printf("%d\n", len);//打印链表长度

	p = (NODE*)malloc(sizeof(NODE));
	gets(p->name);
	insert_node(head, p, 1);//在第一个数据结点后插入新结点
	len = length(head);
	printf("%d\n", len);//输出插入新结点后的链表长度
	output(head);//输出链表内容
		
	delete_node(head, 2);//删除第二个结点
	len = length(head);
	printf("%d\n", len);//输出删除结点之后的链表长度
	output(head);

	getchar();
}

int create(NODE* head, int n)//创建结点需要表头指针和创建结点个数作为参数
{
	NODE* p;
	for (; n > 0; n--)
	{
		p = (NODE*)malloc(sizeof(NODE));
		gets(p->name);
		p->link = head->link;
		head->link = p;//表头结点后插入新结点
	}
	return 0;
}

int output(NODE* head)
{
	NODE* p;
	p = head->link;
	while (p != NULL)
	{
		puts(p->name);
		p = p->link;
	}
	return 0;
}

int insert_node(NODE* head, NODE* p, int i)//表头指针,待插入的结点,插入结点的位置(插在第几个数据结点之后)
{
	NODE* q;
	int n = 0;
	for (q = head; n < i && q->link != NULL; ++n)
		q = q->link;   //定位
	p->link = q->link;
	q->link = p;
	return 0;
}

int delete_node(NODE* head, int i)
{
	NODE* p, * q;
	int n;
	for (n = 0, q = head; n < i - 1 && q->link != NULL; ++n)
		q = q->link;  //定位
	if (i > 0 && q->link != NULL)
	{
		p = q->link;
		q->link = p->link;
		free(p);
	}
}

int length(NODE* head)
{
	int len;
	NODE* p;
	for (len = 0, p = head; p->link != NULL; ++len)
		p = p->link;
	return(len);
}

输出结果展示如下:

先创建具有三个数据结点的链表,然后打印链表的长度;然后输入插入结点的name,然后打印链表长度并打印链表内容,接着删除第二个结点,打印此时的链表数据结点长度和链表内容。、

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值