建立一个单向链表,实现查找、删除、插入功能

建立一个单向链表,实现查找、删除、插入功能

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

一、链表是什么?
二、建立步骤
1.建立结点类
2.建立链表类
3.测试主函数

一、链表是什么?

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。结点是链表的基本组成单元,而结点中存储的内容,顾名思义就是内容。而结点中的指针,则是链接每个结点,使之成为链表的关键。

二、建立步骤

1.建立结点类

代码如下:

class Link
{
public:
	int element;
	Link* next = NULL;
};//结点类

2.建立链表类

class List
{
	int num;
	Link* head;//头指针
	Link* curr;//当前指针
	Link* last;//尾指针
public:
	List()
	{
		num = 0;
		head =curr=last= NULL;
	}

	~List()
	{
		num = 0;
		while (head)
		{
			curr = head;
			head = head->next;
			delete curr;
		}
	}
	Link* MoveLast()//返回尾指针
	{
		curr= head; 
		for(int i=0;i<num-1;i++)
			curr = curr->next;
		last = curr;
		return last;
	}
	Link* FindKth(int k)
	{
		if (k > num || k < 1)
			cout << "wrong site."<<endl;
		else
		{
			curr = head;
			for (int i = 0; i < k-1; i++)
				curr = curr->next;
			return curr;
		}
	}
	Link* Find(int x)
	{
		while (curr != NULL && curr->element != x)
			curr = curr->next;
		if (curr->element == x)
			return curr;
		else
			cout << "wrong element."<<endl;
	}
	void Append(Link* PtrL)//从尾部加结点
	{
		if (head == NULL)
			head = PtrL;
		else
		{
			curr = MoveLast();
			curr->next = PtrL;
		}
		num++;
	}
	void Append(int x)//从尾部加结点(重载)
	{
		if (head == NULL)
		{
			head = new Link;
			head->element = x;
			num++;
		}
		else
		{
			curr = MoveLast();
			Link* PtrL = new Link;
			PtrL->element =x;
			curr->next = PtrL;
			num++;
		}
	}
	void Insert(int k, Link* PtrL)//从任意位置加结点
	{
		if (k<1 || k>num + 1)
			cout << "wrong site."<<endl;
		else if (k == 1)
		{
			PtrL->next = head->next;
			head = PtrL;
			num++;
		}
		else
		{
			curr = FindKth(k-1);
			PtrL->next = curr->next;
			curr->next = PtrL;
			num++;
		}
	}
	void Insert(int k, int x)//从任意位置加结点(重载)
	{
		if (k<1 || k>num + 1)
			cout << "wrong site."<<endl;
		else if (k == 1)
		{
			Link* PtrL = new Link;
			PtrL->element = x;
			PtrL->next = head;
			head = PtrL;
			num++;
		}
		else
		{
			Link* PtrL = new Link;
			PtrL->element = x;
			curr = FindKth(k - 1);
			PtrL->next = curr->next;
			curr->next = PtrL;
			num++;
		}
	}
	void Delete(int k)
	{
		int i = 1;
		curr = head;
		if (k<1 || k>num)
			cout << "wrong site."<<endl;
		else if (k == 1)
		{
			if (head != NULL)
			{
				head = curr->next;
				delete curr;
				num--;
			}
			else
				cout << "empty." << endl;
		}
		else
		{
			curr = FindKth(k-1);
			curr->next = curr->next->next;
			delete curr;
			num--;
		}
	}
	void Print()
	{
		curr = head;
		if (head == NULL)
			cout << "empty";
		else
		{
			while (curr != NULL)
			{
				cout << curr->element << '\t';
				curr = curr->next;
			}
			cout << endl << "The length is " << num << endl;
		}
	}

};//链表类

3.测试主函数

int main()//测试主函数
{
	List list1;
	for (int i = 1; i < 6; i++)
	{
		Link *link=new Link;
		link->element = i;
		list1.Append(link);
	}
	//list1.Delete(4);//测试Delete
	
	//cout<<list1.FindKth(2)->element<<endl;//测试FindKth
	
	//cout << list1.Find(5) << endl;//测试Find
	
	//int x;
	//cin >> x;
	//list1.Append(x);//测试Append
	
	//Link* link = new Link;
	//link->element = 24;
	//int k;
	//cin >> k;
	//list1.Insert(k, link);//测试Insert

	int k, x;
	cin >> k >> x;
	list1.Insert(k, x);
	list1.Print();

	return 0;
}

总结

本文章展示了简单的单向链表的建立,尤其要注意到在删除和插入操作中指针的连接顺序千万不可以随意更改),要明白其背后的道理。由于建立结点时候需要new开辟空间,为了防止内存的流失,一定要在析构函数中delete掉

我是刚刚学习数据结构与算法,这是我的第一篇CSDN博客,以后也会不定期地更新,如果有错误,希望大家指出!谢谢大家!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你实现这个功能。首先,定义一个节点结构体,包含数据和指向下一个节点的指针: ```c typedef struct node { int data; struct node* next; } Node; ``` 然后,定义一个全局的头指针和尾指针: ```c Node* head = NULL; Node* tail = NULL; ``` 接下来,实现插入元素的函数。这里提供两种插入方法:在链表尾部插入和在链表任意位置插入。在尾部插入的函数如下: ```c void insertAtTail(int data) { Node* newNode = malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; if (tail == NULL) { head = tail = newNode; } else { tail->next = newNode; tail = newNode; } } ``` 在任意位置插入的函数如下: ```c void insertAtIndex(int index, int data) { Node* newNode = malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; if (index == 0) { newNode->next = head; head = newNode; if (tail == NULL) { tail = head; } } else { Node* current = head; for (int i = 0; i < index - 1; i++) { current = current->next; } newNode->next = current->next; current->next = newNode; if (newNode->next == NULL) { tail = newNode; } } } ``` 接下来,实现删除元素的函数。同样提供两种删除方法:删除链表头部元素和删除任意位置元素。删除头部元素的函数如下: ```c void deleteAtHead() { if (head == NULL) { return; } Node* temp = head; head = head->next; free(temp); if (head == NULL) { tail = NULL; } } ``` 删除任意位置元素的函数如下: ```c void deleteAtIndex(int index) { if (index == 0) { deleteAtHead(); return; } Node* current = head; Node* prev = NULL; for (int i = 0; i < index; i++) { if (current == NULL) { return; } prev = current; current = current->next; } prev->next = current->next; free(current); if (prev->next == NULL) { tail = prev; } } ``` 最后,实现按键查找元素的函数: ```c Node* search(int data) { Node* current = head; while (current != NULL) { if (current->data == data) { return current; } current = current->next; } return NULL; } ``` 这样,一个简单的单向链表实现了,你可以在主函数中通过调用这些函数来实现你的需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值