单链表的基本操作

目录

一、单链表的定义

二、单链表的初始化(实际是建立一个空的单链表) 

三、单链表的建立(尾插和头插)

四、按照位序插入

五、指定结点的后插

六、指定结点的前插(在p结点之前插入元素e)

七、按位序删除(带头结点)思想:将p结点和后面结点互换

八、指定结点删除(删除指定结点p,思想是将p结点和其后面的结点互换)

九、按值查找

十、按位置查找

十一、求表长(带头结点)

十二、销毁(保留头结点,从第一个结点开始释放所有结点)

十三、销毁(销毁所有包括头结点)


一、单链表的定义

typedef struct Lnode//定义单链表的结点类型 
{
	ElemType data;//每个结点存放一个数据元素 
	struct Lnode* next;//指针指向下一个结点 
}Lnode, * LinkList;
Lnode* L;//声明一个指向单链表第一个结点的指针
LinkList L;//声明一个指向单链表第一个结点的指针

 注意:
强调这是一个单链表,使用LinkList
强调这是一个结点,使用Lnode*

二、单链表的初始化(实际是建立一个空的单链表) 

1.不带头结点的单链表
bool InitList(LinkList & L)
{
	L = NULL;
	return true;
}
2.带头结点的单链表
{
	L = (Lnode*)malloc(sizeof(Lnode));
	if (L == NULL)
	  return false;//内存不足,分配失败
	else
	  L->next = NULL;
	  return true;
}

补充: 

判断单链表(无头结点)是否为空
bool Empty(LinkList L)
{
	if (L == NULL)
		return true;
	else
		return false;

}

判断单链表(有头结点)是否为空
bool Empty(LinkList L)
{
	if (L->next == NULL)
		return true;
	else
		return false;

}

三、单链表的建立(尾插和头插)

1.尾插法
LinkList List_Tailnsert(LinkList & L)
{
	ElemType x;
	L = (LinkList)malloc(sizeof(Lnode));//建立头结点
	Lnode* s;
	Lnode* tail = L;//tail为尾指针
	cin >> x;
	while (x != 999)
	{
		s = (Lnode*)malloc(sizeof(Lnode));
		s->data = x;
		tail->next = s;
		tail = s;//tail指向新的表尾结点
		cin >> x;
	}
	tail->next = NULL;//尾结点置空
	return L;
}
2.头插法
LinkList List_HeadInsert(LinkList & L)
{
	Lnode* s;
	L = (LinkList)malloc(sizeof(Lnode));//创建头结点
	L->next = NULL;//初始为空链表
	ElemType x;
	cin >> x;
	while (x != 999)
	{
		s = (Lnode*)malloc(sizeof(Lnode));
		s->data = x;
		s->next = L->next;
		L->next = s;//将新结点插入表中
		cin >> x;
	}
	return L;
}

四、按照位序插入

1.带头结点
bool ListInsert(LinkList& L, int i, ElemType e)
{
	if (i < 1)
		return false;
	Lnode* p;//指针p指向当前扫描到的结点
	int j = 0;//当前p指向的是第几个结点
	p = L;//L指向头结点,头结点是第0个结点(不存在数据)
	while (p != NULL && j < i - 1)//循环找到第i-1个结点
	{
		p = p->next;
		j++;
	}
	if (p == NULL)//此时p指向空(没有存放数据和指针),意味找完了都没有找到
	{
		return false;
	}
	else//找到了
	{
		Lnode* s = (Lnode*)malloc(sizeof(Lnode));
		s->data = e;
		s->next = p->next;
		p->next = s;
		return true;
	}
}

2.不带头结点
bool ListInsert(LinkList & L, int i, ElemType e)
{
	if (i < 1)
		return false;
	if (i == 1)//插入第一个结点
	{
		Lnode* s = (Lnode*)malloc(sizeof(Lnode));
		s->data = e;
		s->next = L;
		L = s;//头指针指向新的结点
		return true;
	}
	Lnode* p;//指针p指向当前扫描到的结点
	int j = 1;//当前p指向的第几个结点
	p = L;
	while (p1 = NULL && j < i - 1)
	{
		p = p->next;
		j++;
	}
	if (p == NULL)
		return false;
	Lnode* s = (Lnode*)malloc(sizeof(Lnode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
}

五、指定结点的后插

bool InsertNextnode(Lnode* p, ElemType e)
{
	if (p == NULL)
		return false;
	Lnode* s = (Lnode*)malloc(sizeof(Lnode));
	if (s == NULL)//分配内存失败
		return false;
	s->data = e;
	s->next = p->next;
	p->next = s;//将结点s连到p之后
	return true;
}

六、指定结点的前插(在p结点之前插入元素e)

bool InsertPriornode(Lnode* p, ElemType e)
{
	if (p == NULL)
		return false;
	Lnode* s = (Lnode*)malloc(sizeof(Lnode));
	if (s == NULL)
		return false;
	s->next = p->next;
	p - next = s;//将新的结点连到p之后
	s->data = p->data;//将p中元素复制到s中
	p->data = e;//将p中元素覆盖为e
	return true;
}

七、按位序删除(带头结点)思想:将p结点和后面结点互换

bool ListDelete(LinkList& L, int i, ElemType& e)
{
	if (i < 1)
		return false;
	Lnode* p;//指针p指向当前扫描到的结点
	int j = 0;
	p = L;
	while (p != NULL && j < i - 1)
	{
		p = p->next;
		j++;
	}
	if (p == NULL)
		return false;
	if (p->next == NULL)//第i-1个结点之后再无其他结点
		return false;
	Lnode* q = p->next;
	q->data = e;
	p->next = q->next;//将*q结点从链中断开
	free(q);
	return true;
}

八、指定结点删除(删除指定结点p,思想是将p结点和其后面的结点互换)

bool Deletenode(Lnode* p)
{
	if (p == NULL)
		return false;
	else if (p->next == NULL)//如果p为最后一个结点
	{
		Lnode* s;
		s = L;
		while (s->next->data!=p->data)
		{
			s = s->next;
		}
		s->next = NULL;
		free(p);
		return true;
	}
	else
        Lnode* q = p->next;//q为p的后面一个结点
	    p->data = p->next->data;//将q中的数据放入p中
	    p->next = q->next;//将*q结点从链中断开
	    free(q);
	    return true;
}

九、按值查找

Lnode* LocateElem(LinkList L, ElemType e)
{
	Lnode* p = L->next;
	while (p != NULL && p->data != e)
	{
		p = p->next;
	}
	return p;
}

十、按位置查找

bool GetElem(LinkList L,int i, ElemType& e)
{
	Lnode* p;
	p = L;
	int j = 0;
	while (p != NULL && j < i )
	{
		p = p->next;
		j++;
	}
	if (p == NULL || j > i)
		return false;
	e = p->data;
	return true;
}

十一、求表长(带头结点)

int Length(LinkList L)
{
	int len = 0;
	Lnode* p = L;
	while (p->next != NULL)
	{
		p = p->next;
		len++;
	}
	return len;
}

十二、销毁(保留头结点,从第一个结点开始释放所有结点)

bool Destroylist(LinkList& L)
{
	Lnode* p, * s;
	s = L->next;
	while (s)
	{
		p = s;
		s = s->next;
		free(p);
	}
}

十三、销毁(销毁所有包括头结点)

bool Destroylist2(LinkList& L)
{
	Lnode* p;
	while (L)
	{
		p = L;
		L = L->next;
		free(p);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值