链表的实现(简单易懂) 王道考研书

一,单链表的初始化

带头结点和不带头节点的单链表操作是不同的。

        带头结点的next域初始化为NULL

bool InitList(LinkList& L)
{
	//带头结点的初始化

	L = (LNode*)malloc(sizeof(LNode));
	L->next = NULL;
	return true;
	
	////不带头节点的初始化
	//L = NULL;
	//return true;

}

二,求链表的长度操作

需要从第一个节点开始依次访问表中的每一个节点,需要一个变量来计数,每访问一个节点+1,直到p->next==NULL 就break,结束循环。返回变量的值

int Length(LinkList& L)
{
	int len = 0;
	LNode* p = L;
	while (p->next != NULL)
	{
		len++;
		p = p->next;  //p指向下一个next
	}
	return len;
}

三,按序号查找节点

从单链表的第一节节点开始,next域从前往后依次查找,一直到第i个为止,返回指针,如果i<len(链表的长度),则您输入有错,直接返回NULL。

LNode* GetElem(LinkList L, ElemType i)
{
	LNode* p = L;
	p = p->next;
	int pos = 0;
	while (pos<i && p!=NULL)
	{
		p->next;
		pos++;
	}
	return p;
}

四,按值查找节点

同理三,遍历链表,直到p->date==i,如果不相等就换到下一个next域,p = p->next;

LNode* LocalElem(LinkList L, ElemType i)
{
	LNode* p = L->next;
	while (p!=NULL && p->date!=i)
	{
		p = p->next;
	}
	return p;
}

五,插入节点操作的过程

插入节点操作将值为e的新节点插入链表中的第i个位置。

  1. 首先判断位置是否合法  if
  2. 然后找到i-1的位置 while
  3. 再插入
    1.  s->date = e;
    2.  s->next = p->next;
    3.  p->next = s;
      !!!!第2句和第三句不能交换!!!!
bool ListInsert(LinkList L, int i, ElemType e)
{
	//首先找到i-1个节点,然后修改next指针
	LNode* p = L;
	int j = 0;
	while (p->next != NULL && j < i - 1)
	{
		p = p->next;
		j++;
	}

	if (p == NULL)
		return false;

	LNode *s= (LNode*)malloc(sizeof(LNode));

	s->date = e;
	s->next = p->next;
	p->next = s;

	return true;
}

六,打印链表

这个很easy

void PrintfList(LinkList L)
{
	LNode* p = L;
	p = p->next;
	while (p!=NULL)
	{
		printf("%d ", p->date);
		p = p->next;
	}
}

七,删除节点i操作

同理六

bool ListDelect(LinkList L, int i,ElemType &e)
{
	LNode* p = L;
	int j = 0;
	while (p->next !=NULL && j<i-1)
	{
		p = p->next;
		j++;
	}
	if (p == NULL || p->next == NULL)
		return false;
	LNode* q = p->next;
	e = q->date;
	p->next = q->next;
	free(q);
	return true;
}

测试的代码


void test1()
{
	LinkList Link;
	ElemType e;
	//链表的初始化
	if (InitList(Link))
		printf("初始化成功!\n");

	printf("链表的表长度为%d\n", Length(Link));

	printf("\n");

	ListInsert(Link, 1, 56);//插入节点操作的过程
	ListInsert(Link, 2, 8);//插入节点操作的过程
	ListInsert(Link, 3, 3);//插入节点操作的过程
	ListInsert(Link, 4, 2);//插入节点操作的过程

	PrintfList(Link);
	printf("\n");

	//按值查找节点
	if ((LocalElem(Link, 40)) != NULL)
		printf("找到了%d ", (LocalElem(Link, 40))->date);
	else
		printf("没找到!");

	printf("\n");
	printf("\n");

	//带头结点的按序号查找节点
	if ((GetElem(Link, 1)) != NULL)
		printf("找到了%d ", (GetElem(Link, 1))->date);
	else
		printf("没找到!");

	printf("\n");
	printf("\n");

	//删除i 的元素
	if ((ListDelect(Link, 0, e)))
		printf("成功删除!删除的值为:%d\n", e);
	else
		printf("输入的位置越界!删除失败\n");
	printf("\n");

	printf("删除后的链表结构:");
	PrintfList(Link);
}

全部代码如下

#pragma warning(disable:4996)
#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;

typedef struct LNode {
	ElemType date;
	struct LNode* next;
}LNode,*LinkList;

//单链表的初始化
bool InitList(LinkList& L)
{
	//带头结点的初始化

	L = (LNode*)malloc(sizeof(LNode));
	L->next = NULL;
	return true;
	
	////不带头节点的初始化
	//L = NULL;
	//return true;

}

//求链表的长度操作
int Length(LinkList& L)
{
	int len = 0;
	LNode* p = L;
	while (p->next != NULL)
	{
		len++;
		p = p->next;  //p指向下一个next
	}
	return len;
}

//按序号查找节点
LNode* GetElem(LinkList L, ElemType i)
{
	LNode* p = L;
	p = p->next;
	int pos = 0;
	while (pos<i && p!=NULL)
	{
		p->next;
		pos++;
	}
	return p;
}

//按值查找节点
LNode* LocalElem(LinkList L, ElemType i)
{
	LNode* p = L->next;
	while (p!=NULL && p->date!=i)
	{
		p = p->next;
	}
	return p;
}

//插入节点操作的过程
bool ListInsert(LinkList L, int i, ElemType e)
{
	//首先找到i-1个节点,然后修改next指针
	LNode* p = L;
	int j = 0;
	while (p->next != NULL && j < i - 1)
	{
		p = p->next;
		j++;
	}

	if (p == NULL)
		return false;

	LNode *s= (LNode*)malloc(sizeof(LNode));

	s->date = e;
	s->next = p->next;
	p->next = s;

	return true;
}

//打印链表
void PrintfList(LinkList L)
{
	LNode* p = L;
	p = p->next;
	while (p!=NULL)
	{
		printf("%d ", p->date);
		p = p->next;
	}
}

//删除节点i操作
bool ListDelect(LinkList L, int i,ElemType &e)
{
	LNode* p = L;
	int j = 0;
	while (p->next !=NULL && j<i-1)
	{
		p = p->next;
		j++;
	}
	if (p == NULL || p->next == NULL)
		return false;
	LNode* q = p->next;
	e = q->date;
	p->next = q->next;
	free(q);
	return true;
}

void test1()
{
	LinkList Link;
	ElemType e;
	//链表的初始化
	if (InitList(Link))
		printf("初始化成功!\n");

	printf("链表的表长度为%d\n", Length(Link));

	printf("\n");

	ListInsert(Link, 1, 56);//插入节点操作的过程
	ListInsert(Link, 2, 8);//插入节点操作的过程
	ListInsert(Link, 3, 3);//插入节点操作的过程
	ListInsert(Link, 4, 2);//插入节点操作的过程

	PrintfList(Link);
	printf("\n");

	//按值查找节点
	if ((LocalElem(Link, 40)) != NULL)
		printf("找到了%d ", (LocalElem(Link, 40))->date);
	else
		printf("没找到!");

	printf("\n");
	printf("\n");

	//带头结点的按序号查找节点
	if ((GetElem(Link, 1)) != NULL)
		printf("找到了%d ", (GetElem(Link, 1))->date);
	else
		printf("没找到!");

	printf("\n");
	printf("\n");

	//删除i 的元素
	if ((ListDelect(Link, 0, e)))
		printf("成功删除!删除的值为:%d\n", e);
	else
		printf("输入的位置越界!删除失败\n");
	printf("\n");

	printf("删除后的链表结构:");
	PrintfList(Link);
}

int main()
{

	printf("\n***************开始测试***************\n");
	test1();
	printf("\n***************测试结束***************\n");



	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值