c++ 链表

删除元素

#include<iostream>
using namespace std;
struct linklist
{
	linklist* next;
	int val;
	linklist(int x) :val(x), next(nullptr){}
};
//再上一个代码里面我们使用的是不用虚拟头结点  在这个代码里面我们使用的是自带虚拟头节点
linklist* f_delett(linklist* head, int val)
{
	//linklist* cur = new linklist(nullptr);上面这么写是不对的 如果想进一步知道为什么不对请去查询
	linklist* cur2 = new linklist(0);//它并不是通过 new 创建的,而是直接在栈上创建的,
	//因为我们使用 linklist* cur2 = new linklist(0); 
	// //这样的方式。栈上分配的内存会在函数执行完毕时自动释放,不需要手动调用 delete。
	cur2->next = head;
	//对于这个虚拟的1头节点  我们可以自己理解为就是也是一个数据  我们之所以要在整一个指针 这个我们就可以对比与上一个没有头街点 我们是如何删除的
	linklist* cur = cur2;
	while (cur->next != nullptr)
	{
		if (cur->next->val == val)
		{
			linklist* p = cur->next;
			cur->next = cur->next->next;
			delete p;
		}
		else
		{
			cur = cur->next;
		}
	}
	head = cur2->next;//这个地方非要这么写  是因为我们害怕 可能删除的就是第一个元素
	delete cur2;//在这个地方我们只需要删除cur然而并不需要删除cur2  因为栈上分配的内存会自动释放
	//只有动态分配的需要认为去删除
	return head;
}
//总而言之就是第一步先创建一个虚拟头节点
//2.就是再像那个没有头节点一样我们来写

//3.再利用新整的再进行删除元素
//4.最后再头
#include<iostream>
//这种代码是没有虚拟头节点的
using namespace std;
//void f_delete(int *arr,int val)
//{
//	while (arr != NULL&&arr->val==val)
//	{
//
//  }
//}    这么写就有问题了  因为这里面这个arr是一个整数指针  没有  val这个成员

struct linklist
{
	int val;
	linklist* next;
	linklist(int x) :val(x), next(nullptr){}//这个就是结构体内部的函数  如果要想进一步了解  可以自己进行查阅
};
//这个就是进行删除  并返回的一个函数
linklist* delette(linklist* head, int val)   //其实仔细看就发现自己写错了   
{ 
	while (head != nullptr && head->val == val)//nullptr 更加类型安全    得利用循环eg1 1 1 1
	{
		head = head->next;
	}
	linklist* cur = head;//这个地方必须这么写,因为果果你不这么相反你直接返回那个head的话相当于其实是你把这个节点就是已经改变了  
	//所以你需要通过另一个来改变
	while (cur != nullptr && cur->next != nullptr)
	{
		              if (cur->next->val == val) {
                ListNode* tmp = cur->next;//这个就是为了防止没有扔进垃圾桶里面  这个后面我会详细写
                cur->next = cur->next->next;//这个就相当于是跳过
                delete tmp;
            } else {
                cur = cur->next;
            }     
		
	}
	return head;
}

设计链表

#include<iostream>
using namespace std;
#include<string>
//先写一个结构体来整一个链表
//struct linklist
//{
//	int val;
//	linklist* next;
//	linklist(int val):val(val),next(nullptr){}
//};
//查询第n个结点的值  但是我们需要向在查询第n个结点的值前  我们需要判断这个链表中元素的个数   
//并且需要初始话链表
//但是你仔细想一想这个初始话链表是不得 利用这个构造函数  相当于是自动调用
//void chu_shilinklist()
//{
//         所以说在这么写就不好了  我们需要开始使用class
//}
class linklist_my
{


public:
	//先整一个结构体的链表
	struct linklist
	{
		int val;
		linklist* next;
		linklist(int val) :val(val), next(nullptr) {}
	};
	//在在对这个链表进行初始化
	linklist_my()
	{
		dummy = new linklist(0);
		size = 0;
	}
	//第一个函数就是查询第n个元素的值
	//但是首先我们需要判断是否合理
	//即利用一个函数  这个函数不仅仅是运用了这个判断合理性  而且还能返回我们想要的值
	//你要的是返回找到第几个结点  
	int f_heli(int n)
	{
		if (n<0 || n>(size - 1))
		{
			return -1;
		}
		linklist* cur = dummy->next;//我之所以每个代码都写这个就是为了不改变我的虚拟头指针 否则我就改变了
		while (n--)//会导致以下的代码都不正常了
		{
			/*if (cur->val == n)
			{
				break;
			}*/
			cur = cur->next;
		}
		return cur->val;
	}
	//下一个函数利用这个在头节点插入一个数  你看写这个代码的时候就不用判断这个传入几个数
	void f_toucha(int val)
	{
		linklist* node = new linklist(val);
		//(1)
		node->next = dummy->next;//从此之后我们在编写代码时候都用这个虚拟头节点
		//(2)
		dummy->next = node;
		//在这个代码中这个1  2两者之间是不可以进行改变的  如果改变就会造成dummy->next这个的消失 倒置后面造成环
	
		size++;
	}
	//下一个函数在链表最后面添加一个结点
	void f_zuitian(int val)
	{
		linklist* nodef = new linklist(val);
		linklist* cur = dummy;
		while (cur->next != nullptr)
		{
			cur = cur->next;
		}
		cur->next = nodef;
		size++;
	}
	//在第n个节点的位置插入一个结点  这个只需考虑是否过界问题
	void addn_cha(int n, int vall)
	{
		if (n > size)return;//这个其实就是不存在
		if (n < size)size = 0;//这个就是再最开头
		linklist* node = new linklist(vall);//先创建一个数值节点
		linklist* cur = dummy;//这个中 我们一定要切记这个dummy是我们正好的虚拟头节点 然而这个cur是我们接下来要整的 来进行改变的节点
		while (n--)
		{
			cur = cur->next;
		}
		node->next = cur->next;
		cur->next = node;
		size++;
	}
	//删除第n个结点  这个删除一个节点  其实写的有问题  因为删除  需要用到delete
	void shan_delete(int n)
		//所以说  你不仅需要给他删了  你还需要  给他正确的扔进垃圾桶
	{
		if (n >= size || n < 0)
		{
			return;
		}
		linklist* cur = dummy;

		while (n--)
		{
			cur = cur->next;
		}
		//像以下这样做才能正确的扔进垃圾桶2
		linklist* tmp = cur->next;
		cur->next = cur->next->next;
		delete tmp;//这个就是叫做清空内存
		//以下这部是为了防止这个以下的程序不小心使用了tmp
		tmp = nullptr;
		size--;
	}
	void shuchulian()
	{
		linklist* cur = dummy;//每一个函数都要这么写 因为这样写 我们使用的是cur
		while (cur->next != nullptr)
		{
			cout << cur->next->val << " ";
			cur = cur->next;
		}
		cout << endl;
	}

private:
	int size;
	linklist* dummy;//如果把这个放在上面的话就是相当于这上面没有linklist这个结构体
};


int main()
{
	int n;
	cin >> n;
	linklist_my p;
	while (n--)
	{
		string s;
		cin >> s;
		if (s == "H")
		{
			int num;
			cin >> num;
			p.f_toucha(num);
		}
		if (s == "D")
		{
			int num;
			cin >> num;
			p.shan_delete(num);
		}
		if (s == "I")
		{
			int k, x;
			cin >> k >> x;
			p.addn_cha(k, x);
		}
	}
	p.shuchulian();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值