数据结构——线性表:链表

数据结构——线性表:链表

1.Definition and notice
(1)每个数据ai除了存储其本身信息之外,还需要存储一个指示其直接后继信息的地址。一个元素分为数据域、指针域。
(2)头结点:链表里的第一个结点,指针域存放首元结点地址。
头指针:指向第一个结点的指针。若有头结点,则指向头结点
链表
下图为带有头结点的链表
在这里插入图片描述
2.代码
(1)定义
a.别名PNODE 就是 struct node *,别名NODE就是 struct node。注意定义的方法。
b.malloc()函数的头文件为stdlib.h

#include<stdio.h>
#include<stdlib.h>
#define ERROR 0
#define OK    1
typedef struct node    //typedef 用于取struct node 的别名
{
	int data;
	struct node *next;
}*PNODE,NODE;          //别名PNODE 就是 struct node *   别名NODE就是 struct node

(2)main函数

int main()
{
	PNODE init();    //链表初始化
	void insertf(PNODE head, int newdata);  //链表插入头插法
	void insertl(PNODE head, int newdata);  //链表插入尾插法
	void print(PNODE head);  //打印链表
	void frlist(PNODE head);    //释放链表

	//大话数据结构
	int getele(PNODE head, int i, int *e);    //获取第i个结点的元素
	int inserti(PNODE head, int i, int e);   //单链表第i个数据插入结点
	//在链表第i个位置之前插入行的数据元素e,从而e为第i个结点。
	int deletei(PNODE head, int i);           //删除第i个结点

	PNODE head = init();
	return 0;
}

(3)链表初始化函数(返回头指针head)

PNODE init()
{
	PNODE head = (PNODE)malloc(sizeof(NODE));
	head->next = NULL;

	return head;
}

(4)头插法和尾插法
a.头插法
在这里插入图片描述

void insertf(PNODE head, int newdata)   //头插法
{
	PNODE current;
	current = (PNODE)malloc(sizeof(NODE));
	current->data = newdata;
	current->next = head->next;
	head->next = current;
}

b.尾插法
在这里插入图片描述

void insertl(PNODE head, int newdata)
{
	PNODE p, current;
	current = (PNODE)malloc(sizeof(NODE));
	current->data = newdata;
	p = head;
	while (p->next != NULL)
	{
		p = p->next;
	}
	p->next = current;
	current->next = NULL;
}

(5)打印函数

void print(PNODE head)
{
	PNODE p;
	p = head->next;
	while (p != NULL)
	{
		printf("%d->", p->data);
		p = p->next;
	}
	printf("NULL\n");
}

(6)链表释放函数

void frlist(PNODE head)   //释放链表
{
	PNODE p, temp;
	p = head;
	while (p != NULL)
	{
		temp = p->next;
		free(p);
		p = temp;
	}
}

(7)获取第i个结点元素的函数
找到**a[i]**这个结点
在这里插入图片描述

int getele(PNODE head, int i, int *e)
{
	int j = 1;
	PNODE p = head->next;       //p指向第一个结点,j=1。
	while (p != NULL && j < i)
	{
		p = p->next;  
		j++;
	}                           //循环结束 此时p指向第i个结点
	if (p == NULL || j > i)
		return ERROR;
	*e = p->data;
	return OK;
}

(8)链表的插入函数
在链表第i个结点之前插入行的数据元素e,从而e所在结点为第i个结点。首先要找到a[i-1]这一结点。
注意:此处函数指针p初始化时与 getele()函数不同
此处为p=head;而getele()函数中为p=head->next;

int inserti(PNODE head, int i, int e)  //单链表第i个数据插入结点
{
	PNODE p,current;
	int j = 1; 
	p = head;       //p指向头结点,j=1。注意此处与getele()不同
	while (p != NULL && j < i)
	{
		p = p->next;
		j++;
	}               //循环结束 此时p指向第a[i-1]个结点
	if (p == NULL || j > i)   
		return ERROR;
	current = (PNODE)malloc(sizeof(NODE));
	current->data = e;
	current->next = p->next;
	p->next = current;
	return OK;
}

(9)链表的结点删除函数
注意:此处if判断条件为if (p->next == NULL || j > i)
不同于inserti()函数中的if (p == NULL || j > i)
在这里插入图片描述

int deletei(PNODE head, int i)  
{
	PNODE p,current;
	p = head;               //此处与inserti()相同,不同于getele()
	int j = 1;
	while (p != NULL && j < i)    //此处大话书上P65有问题
	{
		p = p->next;
		j++;
	}                       //循环结束 此时p指向第a[i-1]个结点
	if (p->next == NULL || j > i) 
	//此处不同于inserti()函数,判断a[i]存在与否
		return ERROR;
	current = p;
	p->next = p->next->next;
	free(current);
	return OK;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值