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;
    }



  • 相关阅读:
    随机选择
    Creating Apps With Material Design —— Defining Shadows and Clipping Views
    HDU 1853Cyclic Tour(网络流之最小费用流)
    053第502题
    【ThinkingInC++】64、重载new和delete,来模仿内存的分配
    Android设置里面默认存储器选项(default write disk)的实现
    Transparency Tutorial with C#
    ssh远程登录linux live系统
    JAVA把字符串当作表达式执行
    [Head First设计模式]生活中学设计模式——组合模式
  • 原文地址:https://www.cnblogs.com/lytwajue/p/7098665.html
Copyright © 2011-2022 走看看