个人笔记--(带头结点)单链表的一些基本操作,头插法尾插法

本文详细介绍了链表的基本操作,包括初始化、创建新节点、判断是否为空、获取长度、清空和销毁链表等,并深入讲解了如何在指定位置插入和删除元素、获取特定位置的元素及其位置等实用技巧。

链表

头文件以及结构体定义放最前面了,主函数就不写了,想必理解了以下子函数,主函数不是有手就行?

#include<bits/stdc++.h>
using namespace std;
#define OK 1
#define ERROR 0
#define Listsize 100
typedef int ElemType;
typedef int Status;
typedef struct LNode{
	ElemType data;//数据域 
	struct LNode *next;//指针域 
}Node, *pNode;//这里举个例子:Node *L == pNode L,两者等价 

初始化链表

pNode InitList()
{
	pNode pHead=(pNode)malloc(sizeof(Node));//申请内存空间
	if(NULL==pHead) exit(-1);//空间不足,分配失败
	pHead->next=NULL;//设置头结点
	return pHead;
}

创建新结点

pNode CreateNode(int data)//创建新结点,顺便把元素插进去
{
	pNode NewNode=(pNode)malloc(sizeof(Node));//同样,申请内存空间
	if(NULL==NewNode) exit(-1);
	NewNode->data=data;//赋值
	NewNode->next=NULL;//指向空
	return NewNode;
}

链表判空

Status EmptyList(pNode &pHead)
{
	if(pHead->next==NULL)//如果头结点指针指向空,说明链表内没有元素
		return 1;
	else
		return 0;
}

求链表长度

Status NumberList(pNode &pHead)
{
	pNode p=pHead->next;//用指针p表示头结点的指针
	int len=0;//初始化长度为0
	while(p!=NULL)//当p指向不为空时
	{、
		len++;//长度+1
		p=p->next;//p指向p的下一位
	}
	return len;//返回链表长度
} 

清空链表

Status ClearList(pNode &pHead)
{
	pNode p,q;//两个指针,是为了向前走的同时释放前一位。用这个主要是为了保住pHead不被释放
	p=pHead->next;//p初始化为头结点的指针指向
	while(p!=NULL)
	{
		q=p->next;//先将p->next保存在q里
		free(p);//释放p
		p=q;//再把p->next赋值给p,向前走
	}
	pHead->next=NULL;//注意,最后将头结点指针初始化为空
	return OK;
}

销毁链表

Status DestroyList(pNode &pHead)
{
	pNode q;//pHead这里充当清空操作的p,因为要销毁pHead
	while(pHead)
	{
		q=pHead->next;
		free(pHead);
		pHead=q;//同清空操作
	}
	return OK;
}

在指定位置插入元素

Status InsertList(pNode &pHead,int loc,int e)//在loc位置插入e
{
	pNode p=pHead;//用p来代替pHead
	pNode pNew=(CreateNode(e));//创造新结点并把e赋值进去
	if(loc<1 || loc>NumberList(p)+1)//讨论位置,这里+1是因为也可以插入到最后一个元素的后一位
		return ERROR;
	for(int i=1;i<loc;i++)
		p=p->next;//for循环让p指向要插入元素位置
	pNew->next=p->next;//让pNew指向p的下一位
	p->next=pNew;//让p指向pNew,这样就变成是p->pNew->原来的p->next,使pNew插入两者中间了
	return OK;
}

在指定位置删除元素

Status DelElem(pNode &pHead,int len)
{
	if(len<1 || len>NumberList(pHead))//讨论位置
		return ERROR;
	pNode p=pHead,q;
	for(int i=1;i<len;i++)
		p=p->next;//for循环让p指向要删除元素位置
	q=p->next;//q先存储要删除的结点
	p->next=p->next->next;//让p->next指向p->next->next,一个跳过的过程,算法技巧
	free(q);//释放要删除的结点
	return OK;
}

获取指定位置的元素

Status GetElem(pNode &pHead,int len,int &e)//获取len位置的元素存储到e中
{
	if(len<1 || len>NumberList(pHead))//讨论位置
		return ERROR;
	int pLen=1;//从位置1开始查找
	pNode p=pHead->next;//第一个结点(不算头结点)
	while(pLen<len)
	{
		p=p->next;
		pLen++;
	}
	e=p->data;//找到后赋值给e
	return OK;
}

获取指定元素的位置

Status GetLocal(pNode &pHead,int e,int &len)//获取元素e的位置赋值给len
{
    pNode p=pHead->next;//首位开始
    len=0;
    while(p!=NULL)//一直往后找
	{
		len++;//找一个len加1
		if(p->data==e)
			return OK;//找到了
        p=p->next;//当前没找到p就后移,继续while循环找
    }
    return ERROR;//while循环跑完了都没有找到元素e,就是没找到呗
}

求前驱

这里直接调用了GetLocal函数和GetElem函数,有兴趣的同学可以拆开写。(无非就是把GetLocal函数和GetElem函数重新写了一遍)

				cout<<"请输入元素查找前驱"<<endl;
				cin>>e;
				if(!GetLocal(L,e,len))
					cout<<"输入元素不存在"<<endl;
				else if(len==1)
					cout<<"第一个元素没有前驱"<<endl;
				else
				{
					int val;
					GetElem(L,len-1,val);//求前驱,位置-1
					cout<<"前驱为:"<<val<<endl;
				}

求后继

也是调用俩函数

				cout<<"请输入元素查找后继"<<endl;
				cin>>e;
				if(!GetLocal(L,e,len))
					cout<<"输入元素不存在"<<endl;
				else if(len==NumberList(L))
					cout<<"最后一个元素没有后继"<<endl;
				else
				{
					int val;
					GetElem(L,len+1,val);//求后继,位置+1
					cout<<"后继为:"<<val<<endl;
				}

显示链表元素

Status ShowList(pNode &pHead)
{
	pNode p=pHead->next;//从首位开始查询
	while(p)
	{
		cout<<p->data<<' ';//查到一个输出一个
		p=p->next;//指针后移
	}
	cout<<endl;
}

尾插法和头插法

尾插法就是顺序插入,把元素一个一个接在链表尾部

//尾插法
				pNode pTail;
				LA=InitList();//初始化链表LA
				pTail=LA;
				pTail->next=NULL;
				cout<<"请输入要插入元素个数:";
				cin>>len;
				cout<<endl<<"请输入要插入的元素:"<<endl;
				for(int j=1;j<=len;j++)
				{
					cin>>e;
					pNew=CreateNode(e);
					pTail->next=pNew;//尾部接上
        			pTail=pNew;//新结点为新的尾部
				}
				cout<<"插入元素完成"<<endl<<"该链表为:";
				ShowList(LA);

尾插法的最核心部分就是这两步,请仔细揣摩

					pTail->next=pNew;
        			pTail=pNew;

头插法就是顺序插入,把元素一个一个接在链表头部(但是在头结点后)

//头插法
				pNode P;
				LB=InitList();
				P=LB;
				cout<<"请输入要插入元素个数:";
				cin>>len;
				cout<<endl<<"请输入要插入的元素:"<<endl;
				for(int i=1;i<=len;i++)
				{
					cin>>e;
					pNew=CreateNode(e);
					pNew->next=P->next;//新结点指向原第一位,使原来的第一位变为第二位
					P->next=pNew;//新结点为新的第一位
				}
				cout<<endl;
				cout<<"插入元素完成"<<endl<<"该链表为:";
				ShowList(LB);

头插法的最核心部分就是这两步,请仔细揣摩

					pNew->next=P->next;
					P->next=pNew;

饿死了,吃饭去了~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值