循环单链表(C/C++)

假如链表中有多个数组为5的,怎么删除呢? 

//循环单链表(L指向表头)
#include<iostream>
#include<algorithm>

using namespace std;

typedef struct LNode {
	int data;
	struct LNode* next;
}LNode,*LinkList;
//强调节点用 LNode,强调链表用LinkList;
//初始化链表 
bool InitList(LinkList& L)
{
	L = (LNode*)malloc(sizeof(LNode));//动态分配一个表头
	if (L == NULL)
	{
		return false;
	}
	L->next = L;
	return true;
}
//头插法,带头结点
LinkList List_HeadInsert(LinkList& L)
{
	InitList(L);//初始化
	LNode* s, * r = L;
	bool isFirst = true;
	int x;
	while (cin >> x&&x!=-1)
	{
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;
		s->next = L->next;
		L->next = s;
		if (isFirst)//将r指向第一个结点,只进行一次操作,后续在插入不在执行此操作。
		{
			r = s;
			isFirst = false;
		}
	}


	r->next = L;//尾指针指向表头
	return L;
}
//尾插法,带头结点。
LinkList List_TailInsert(LinkList& L)
{
	InitList(L);
	LNode* s, * r = L;
	int x;
	while (cin >> x && x != -1)
	{
	   s = (LNode*)malloc(sizeof(LNode));
		{
		   s->data = x;
		   r->next = s;
		   r = s;
		
		
		}
		r->next = L;
		return L;
	}


}
//打印循环单链表。
void print(LinkList L)
{
	LNode* s = L->next;
	cout << "打印当前链表" << endl;
	while (s!= L)
	{
		cout << s->data << " ";
		s = s->next;//一直向后指
	}
	cout << endl;


}
//按位查找,找到数据域等于e的结点
LNode* LocateElem(LinkList L, int e)
{
	LNode* p = L->next;
	while (p != L && p->data != e)
	{
		p = p->next;
	}
	return p;
}
//按位查找,返回第i个元素
LNode* GetElem(LinkList L, int i)
{
	if (i < 0)
	{
		return NULL;
	}
	int j = 1;
	LNode* p = L->next;
	while (p != L && j < i)
	{
		p = p->next;
		j++;
	}
	return p;
}
//统计单链表的长度
int Length(LinkList L)
{
	int len = 0;
	LNode* p = L;
	while (p->next != L)//因为是循环单链表,所以指到最后一个就行。
	{
		len++;
		p = p->next;
	}
	return len;

}
//后插操作,在节点p之后插入元素e;
bool InsertNextNode(LNode* p, int e)
{
	if (!p)
	{
		return false;
	}
	LNode* s = (LNode*)malloc(sizeof(LNode));
	if (!s)
	{
		return false;
	}
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;

}
//带头结点的插入操作,在第i个位置插入元素e
bool ListInsert(LinkList& L,int i,int e)
{
	if (i < 1)
	{
		return false;
	}
	LNode* p = GetElem(L, i - 1);//找到前一个节点
	if (!p)
	{
		return false;
	}
	return InsertNextNode(p, e);//在这个节点后面插入数据,就是i的位置插入。


}
//前插操作,在p节点前插入元素e,
bool InsertPriorNode(LNode* p, int e)
{
	if (!p)
	{
		return false;

	}
	LNode* s = (LNode*)malloc(sizeof(LNode));
	if (!s)
	{
		return false;

	}
	s->next = p->next;
	p->next = s;
	s->data = p->data;
	p->data = e;
	return true;
}
//前插操作,在节点p之前插入节点s
bool InsertPriorNode(LNode* p, LNode* s)
{
	if (!p || !s)
	{
		return false;
	}
	s->next = p->next;
	p->next = s;
	swap(s->data, p->data);
	return true;
}
//删除位序i的节点,e是i节点的值,
bool ListDelete(LinkList& L, int i, int& e)
{
	if (i < 1)
	{
		return false;
	}
	LNode* p = GetElem(L, i - 1); // 获取前一个元素
	if (p==NULL || p->next==L)
	{
		return false;
	}
	LNode* q = p->next; // 待删除节点
	e = q->data;
	p->next = q->next; // 修改前一个节点的指针
	free(q); // 释放被删除节点的内存
	return true;
}
//删除指定节点
bool DeleteNode(LinkList& L,LNode*p)//把这个p节点的值赋给p的下一个节点q,假如p是最后一个节点就让q的下一个节点成为首节点,最后释放q
{
	LNode* q =p ->next;
	p->data = q->data;
	p->next = q->next;
	if (L == q)//如果要删除的是尾节点
	{
		L = p;
	}
	free(q);
	return true;


}
//判断链表是否为空
bool Empty(LinkList L)
{
	if (L->next == L)
	{
		return true;
	}

	return false;
}
//判断是否为表尾节点
bool isTail(LinkList L, LNode* p)
{
	if (p->next = L)
	{
		return true;
	}
	return false;
}
int main()
{
	LinkList L;
	cout << "请输入链表的数值" << endl;
	List_HeadInsert(L);
	print(L);
	cout << "链表的第一个元素" << GetElem(L, 1)->data << endl;
	cout << "链表的第五个元素" << GetElem(L, 5)->data << endl;
	cout << "链表的长度" << Length(L) << endl;
	int e;
	ListDelete(L, 5, e);
	cout << "删除的第5个元素是" << e << endl;
	print(L);
	ListDelete(L, 1, e);
	cout << "删除的第一个元素是" << e << endl;
	print(L);
	ListInsert(L, 1, e);
	cout << "插入的第一个元素是" << e << endl;
	print(L);
	cout<<"找到数值为5的节点并删除"; 
	LNode* s = LocateElem(L, 5);//按值查找。
	DeleteNode(L, s);
	print(L);

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值