【C++】通用单链表

31 篇文章 1 订阅
1 篇文章 0 订阅

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值