zoukankan      html  css  js  c++  java
  • 【c++版数据结构】之循环单链表的实现(带头结点以及尾节点)

    所实现的循环单链表的结构例如以下图所看到的:


    循环单链表的实现,和上一篇文章单链表的实现大致同样点击打开链接略有差别:

    1:循环推断的条件不再是s == NULL或者s->next == NULL,而是他们是否等于头指针。2: 断开链表时的处理,尾节点的next不是NULL,而是指向头结点

    详细细节參考上一篇文章微笑

    头文件:SCList.h

    #ifndef SCLIST_H
    #define SCLIST_H
    
    #include<iostream>
    #include<cassert>
    using namespace std;
    
    typedef enum{ FALSE, TRUE }Status;
    
    template<class Type>
    class List;
    
    template<class Type>
    class ListNode
    {
    	friend class List<Type>;
    private:
    	Type data;
    	ListNode *next;
    public:
    	ListNode() :data(Type()), next(NULL){}
    	ListNode(Type d, ListNode<Type> *n = NULL) :data(d), next(n){}
    	void SetData(Type d){ data = d; }
    	Type GetData()const{ return data; }
    	~ListNode(){}
    };
    
    template<class Type>
    class List
    {
    private:
    	ListNode<Type> *first;
    	ListNode<Type> *last;
    	size_t         size;
    public:
    	List()
    	{
    		ListNode<Type> *s = new ListNode<Type>;
    		assert(s != NULL);
    		first = last = s;
    		last->next = first;
    	}
    	~List()
    	{
    		destory();
    	}
    	Status push_back(const Type &x)
    	{
    		ListNode<Type> *s = new ListNode<Type>(x);
    		if (s == NULL)
    			return FALSE;
    		last->next = s;
    		last = s;
    		last->next = first;
    		size++;
    		return TRUE;
    	}
    	void show_list()
    	{
    		ListNode<Type> *s = first->next;
    		while (s != first)
    		{
    			cout << s->data << "->";
    			s = s->next;
    		}
    		cout << "Nul." << endl;
    	}
    	Status push_front(const Type &x)
    	{
    		ListNode<Type> *s = new ListNode<Type>(x);
    		if (s == NULL)
    			return FALSE;
    		s->next = first->next;
    		first->next = s;
    		if (size == 0)
    		{
    			last = s;
    			last->next = first;//---------------->能够省略,think
    		}
    		size++;
    		return TRUE;
    	}
    	Status pop_back()
    	{
    		if (size == 0)//
    		{
    			cout << "循环单链表已空,无法尾删" << endl;
    			return FALSE;
    		}
    		ListNode<Type> *s = first;
    		while (s->next != last)
    			s = s->next;
    		delete last;
    		last = s;
    		last->next = first;
    		size--;
    		return TRUE;
    	}
    	Status pop_front()
    	{
    		if (size == 0)//
    		{
    			cout << "循环单链表已空。无法头删" << endl;
    			return FALSE;
    		}
    		ListNode<Type> *s = first->next;
    		first->next = s->next;
    		delete s;
    		if (size == 1)
    		{
    			last = first;
    			last->next = first;//能够省略-------------->
    		}
    		size--;
    		return TRUE;
    	}
    	Status insert_val(const Type &x)
    	{
    		ListNode<Type> *s = first;
    		while (s->next != first && s->next->data < x)
    			s = s->next;
    		if (s->next == first)
    			push_back(x);
    		else
    		{
    			ListNode<Type> *p = new ListNode<Type>(x);
    			assert(p != NULL);
    			p->next = s->next;
    			s->next = p;
    			size++;
    		}
    		return TRUE;
    	}
    	ListNode<Type>* find(const Type &x)
    	{
    		if (size == 0)
    			return NULL;
    		ListNode<Type> *s = first->next;
    		while (s != first)
    		{
    			if (s->data == x)
    				return s;
    			s = s->next;
    		}
    		return NULL;
    	}
    	Status delete_val(const Type &x)
    	{
    		ListNode<Type> *s = find(x);
    		if (s == NULL)
    		{
    			cout << "该元素不存在,无法删除" << endl;
    			return FALSE;
    		}
    		if (s == last)
    		{
    			pop_back();
    		}
    		else
    		{
    			ListNode<Type> *p = s->next;
    			s->data = p->data;
    			s->next = p->next;
    			if (p == last)//------------------->>注意
    			{
    				last = s;
    			}
    			delete p;
    			size--;
    		}
    		return TRUE;
    	}
    	//从第一个节点处断开,一分为二,头结点和第一个节点成为一个单独的循环单链表
    	//将剩余的节点依次按值插入该链表
    	void sort()
    	{
    		if (size == 0 || size == 1)
    			return;
    		ListNode<Type> *s = first->next;
    		ListNode<Type> *p = s->next;
    		last = s;	
    		last->next = first;
    		while (p != first)
    		{
    			s = p;
    			p = p->next;
    			//insert_val(s->data);
    			//delete s;
    			ListNode<Type> *q = first;
    			while (q->next != NULL && q->next->data < s->data)
    			{
    				q = q->next;
    			}
    			if (q->next == NULL)
    			{
    				last->next = s;
    				last = s;
    				last->next = first;
    			}
    			else
    			{
    				s->next = q->next;
    				q->next = s;
    			}
    		}
    	}
    	//从第一个节点处断开,一分为二,头结点和第一个节点成为一个单独的循环单链表
    	//将剩余的节点依次进行头插
    	void reserve()
    	{
    		if (size == 0 || size == 1)
    			return;
    		ListNode<Type> *s = first->next;
    		ListNode<Type> *p = s->next;
    		last = s;
    		last->next = first;
    		while (p != first)
    		{
    			s = p;
    			p = p->next;
    			s->next = first->next;
    			first->next = s;
    		}
    	}
    	size_t lenth()
    	{
    		return size;
    	}
    	void clear()
    	{
    		if (size == 0)
    			return;
    		ListNode<Type> *s = first->next;
    		while (s != first)
    		{
    			if (size == 1)
    			{
    				last = first;
    				last->next = first;
    			}
    			else
    			{
    				first->next = s->next;
    			}
    			delete s;
    			size--;
    			s = first->next;
    		}
    	}
    	ListNode<Type>* next(ListNode<Type> *s)
    	{
    		if (s == last)//最后一个节点没有后继
    			return NULL;
    		else
    			return s->next;
    	}
    	ListNode<Type>* prio(ListNode<Type> *s)
    	{
    		if (s == first->next)//第一个节点没有前驱
    			return NULL;
    		ListNode<Type> *p = first;
    		while (p->next != s)
    		{
    			p = p->next;
    		}
    		return p;
    	}
    	void destory()
    	{
    		clear();
    		delete first;
    		first = last = NULL;
    	}
    };
    #endif
    測试文件:main.cpp

    #include"SCList.h"
    
    int main()
    {
    	List<int> mylist;
    	int item;
    	int n;
    	int select = 1;
    	//ListNode<int> *p;
    	while (select)
    	{
    		cout << "*************************************** *" << endl;
    		cout << "*[1] push_back           [2] push_front *" << endl;
    		cout << "*[3] show_list           [4] pop_back   *" << endl;
    		cout << "*[5] pop_front           [6] insert_val *" << endl;
    		cout << "*[7] lenth               [8] find       *" << endl;
    		cout << "*[9] merge               [10] delete_val*" << endl;
    		cout << "*[11] sort               [12] reserve   *" << endl;
    		cout << "*[13] next               [14] clear     *" << endl;
    		cout << "*[15] prio               [0] quit_system*" << endl;
    		cout << "请选择:>";
    		cin >> select;
    		switch (select)
    		{
    		case 1:
    			cout << "请输入要插入的元素(-1结束):>";
    			while (cin >> item, item != -1)
    			{
    				mylist.push_back(item);
    			}
    			break;
    		case 2:
    			cout << "请输入要插入的元素(-1结束):>";
    			while (cin >> item, item != -1)
    			{
    				mylist.push_front(item);
    			}
    			break;
    		case 3:
    			mylist.show_list();
    			break;
    		case 4:
    			mylist.pop_back();
    			break;
    		case 5:
    			mylist.pop_front();
    			break;
    		case 6:
    			cout << "请输入要插入的元素:";
    			cin >> item;
    			mylist.insert_val(item);
    			break;
    		case 7:
    			cout << "长度为:" << mylist.lenth() << endl;
    			break;
    		case 8:
    			cout << "请输入要查找的元素:";
    			cin >> item;
    			if (mylist.find(item))
    				cout << "it's found" << endl;
    			else
    				cout << "it's not exist" << endl;
    			break;
    		case 9:
    			cout << "请输入要删除的位置:";
    			cin >> n;
    			//mylist.delete_pos(n,item);
    			break;
    		case 10:
    			cout << "请输入要删除的元素:";
    			cin >> item;
    			mylist.delete_val(item);
    			break;
    		case 11:
    			mylist.sort();
    			break;
    		case 12:
    			mylist.reserve();
    			break;
    		case 13:
    			cout << "请输入要查找后继的元素:";
    			cin >> item;
    			//p = mylist.next(item);
    			//if (p != NULL)
    			//	cout << p->GetData() << endl;
    			break;
    		case 14:
    			mylist.clear();
    			break;
    		default:
    			break;
    		}
    	}
    	system("pause");
    	return 0;
    }



  • 相关阅读:
    rs
    stm32f767 usoc3
    stm32f767 RTT 日志
    stm32f767 标准库 工程模板
    stm32f767 HAL 工程模板
    docker tab 补全 linux tab 补全
    docker anconda 依赖 下载 不了
    docker run 常用 指令
    linux scp 命令
    Dockerfile 常用参数说明
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7098665.html
Copyright © 2011-2022 走看看