zoukankan      html  css  js  c++  java
  • 【C++】通用单链表

           在C++的学习中,採用模板类,而採用虚函数实现多态性。达到通用的目的。结点类数据域被改造为指针,而把数据放在一个抽象类中。由指针与之建立联系。

           採用虚函数实现多态性,达到通用的目的。堆内存的分配与释放。关键不是创建,而是释放!

           要特别细致揣摩堆内存的分配与释放,删除一个结点时系统自己主动调用结点类析构函数释放结点占用的动态内存。而结点释放时系统自己主动调用数据域类析构函数释放数据类占用的动态内存,本例中数据类释放时系统自己主动调用虚析构函数来实现释放字符串数据的动态内存。一环套一环。一步都不能错。这是使用动态内存分配的关键。即关键不是创建,而是释放!


           执行时的多态性须要维护一个动态指针表才干正确指向各相关类中的同名虚函数。所以多态与模板比較,模板的效率更高,标准模板库中用容器来泛型化数据结构中的很多算法。

    对数据结构的使用当然借助模板库。

    多态不适用于性能要求非常高的实时应用程序。但继承与多态可用与其他很多其他方面,每一种技术都有能够充分发挥自己能力的地方。

           源码例如以下:有什么不足的地方希望大家能够指出。谢谢大家。

           

    #include<iostream>
    using namespace std;
    
    class Object
    {
    public:
       Object()
       {} 
       virtual void Print()=0;
       virtual ~Object()
       {} 
    }; 
    
    class Node
    {
    private:
    	Object *info;           //数据域用指针指向数据类对象
    	Node   *next;
    public:
    	Node()                  //生成头结点的构造函数
    	{
    		info = NULL;
    		next = NULL;
    	}
    	~Node()                 //析构函数
    	{}
    	void InsertAfter(Node* P)//在当前结点后插入一个结点
    	{
    		Node *s = new Node;
    		s->next = P->next ;
    		P->next = s;
    	}
    	Node* RemoveAfter(Node* P) //删除当前结点的后继结点,返回该结点备用
    	{
    		Node *s = P->next ;
    		P->next = s->next ;
    		free(s);
    		return P;
    	}
    	void Linkinfo(Object* obj) //把数据对象连接到结点
    	{
    		info = obj;
    	}
    	Node* GetNext()const       //返回next
    	{
    		return next;
    	} 
    	Object* GetInfo()const     //返回info
    	{
    		return info;
    	}
    	friend class List;         //以List为友元类。List可直接訪问Node的私有函数
    };
    
    class List
    {
    private:
    	Node *head,*tail;           //链表头指针和尾指针
    public:
    	List()                      //构造函数,生成头结点(空链表)
    	{
    		head = tail = new Node;
    	}
    	~List()                     //析构函数
    	{
    		MakeEmpty();
    		delete head;
    	}
    	void MakeEmpty()            //清空链表。仅仅余表头结点
    	{
    		head->next = NULL;
    	}
    	Node* Find(Object * obj)    //搜索数据域与定值同样的结点。返回该结点的地址
    	{
    		Node *s = head->next;
    		while(s->GetInfo() != obj)
    		{
    			s = s->next;
    		}
    		if(s == NULL)
    		{
    			return NULL;
    		}
    		return s;
    	}
    	int Length()                 //计算单链表长度
    	{
    		int count = 0;
    		Node *s = head->next;
    		while(s != NULL)
    		{
    			s = s->next ;
    			count++;
    		}
    		return count;
    	}
    	void PrintList()             //打印链表的数据域
    	{
    		Node *p = head->next;
    		while(p != NULL)
    		{
    			p->GetInfo()->Print();
    			p = p->next ;
    		}
    		cout<<endl;
    	}
    	void InsertFront(Node* p)    //可用来向前生成链表
    	{
    		p->next = head->next;
    		head->next = p;
    	}
    	void InsertRear(Node* p)     //可用来向后生成链表
    	{
    		tail->next = p;
    		tail = p;
    	}
    	void InsertOrder(Node* p)    //按升序生成链表
    	{
    		Node * s = head;
    		while(s->next->GetInfo() <= p->GetInfo())
    		{
    			s = s->next ;
    		}
    		p->next = s->next ;
    		s->next = p;
    	}
    	Node* CreatNode()            //创建一个结点(孤立结点)
    	{
    		Node *s = new Node;
    		return s;
    	}
    	void DeleteNode(Node* p)     //删除指定结点
    	{
    		Node *s = head;
    		while(s->next != p)
    		{
    			s = s->next ;
    		}
    		s->next = p->next ;
    		free(p);
    	}
    	Node* GetHead()const        
    	{
    		return head;
    	}
    };
    
    class Int : public Object
    {
    public:
    	Int(int x=0):m_x(x)
    	{}
    	void Print()
    	{
    		cout<<m_x<<" ";
    	}
    private:
    	int m_x;
    };
    
    class String : public Object
    {
    public:
    	String(const char *str="")
    	{
    		m_data = new char[strlen(str)+1];
    		strcpy(m_data,str);
    	}
    	void Print()
    	{
    		cout<<m_data<<" ";
    	}
    private:
    	char *m_data;
    };
    
    void main()
    {
    	List mylist;
    	Node *pnode = NULL;
    	Int  *pi = NULL;
    	for(int i=1; i< 6; ++i)
    	{
    		pnode = mylist.CreatNode();
    		pi = new Int(i);
    		pnode->Linkinfo(pi);
    		mylist.InsertFront(pnode);
    	}
    	mylist.PrintList();
    	cout<<mylist.Length()<<endl;
    
    	mylist.MakeEmpty();
    	cout<<mylist.Length()<<endl;
    
    	List youlist;
    	char *str[6] = {"fjafjla","fjalla","ahfnj","xkk","fdjk","asdfg"};
    	String *ps = NULL;
    	for(i=0; i<6; ++i)
    	{
    		pnode = youlist.CreatNode();
    		ps = new String(str[i]);
    		pnode->Linkinfo(ps);
    		youlist.InsertRear(pnode);
    	}
    
    	youlist.PrintList();
    	cout<<youlist.Length()<<endl;
    
    	youlist.MakeEmpty();
    	cout<<youlist.Length()<<endl;
    }


  • 相关阅读:
    作业8: 软件工程学习总结
    用户体验——南通大学教务学生管理系统
    “构建之法互动游戏”感想
    第二次作业
    音乐播放器的发展演变
    C++用法的学习心得
    一、最后一次作业:软件工程学习总结
    设计一款给爸爸妈妈用的手机
    附加题1—— 我想搞懂的软工问题
    计算机病毒软件的发展演变
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6943519.html
Copyright © 2011-2022 走看看