variant list--不同结点元素可能不同的链表

         variant list同样基于简单链表,不同结点的元素不同但是为了能够链表元素的插入和读取,必须提供相同的接口,所以可以通过继承还保持相同的接口,通过多态来保证各个结点元素的输出。

         这一举一个简单的例子--冰糖葫芦。冰糖葫芦是经典的小吃,传统的冰糖葫芦统一由山楂串联而成,类似于list,而在现实生活中我们经常能看到串橘子的、苹果的、甚至黄瓜的冰糖葫芦,这就类似于我们的chunk list。这里我们假设能够做冰糖葫芦的东西都为水果,山楂、苹果、橘子都认为是水果所以才能做冰糖葫芦。那么水果就是冰糖葫芦统一的接口,每个冰糖葫芦的结点都要提供一个水果这样的接口,同时要延伸出去一个水果的link去串联下一个水果。同时每种水果都要可以展示出自己是什么水果的接口函数,通过父类水果的指针实现对其的调用,这就是多态的作用。

#include<iostream>
class Fruit
{
	friend class Bingtanghulu;
	protected:
		std::string name;
		std::string color;
		double price;
		Fruit* link;
		Fruit(std::string n, std::string c, double p)
			:name(n),color(c),price(p)
		{
			link = 0;
		}
		virtual void display()const;
		virtual Fruit* getnode(){}
};
class Hawthorn:public Fruit
{
	friend class Bingtanghulu;
	protected:
		std::string taste;
	public:
		Hawthorn(std::string n, std::string c, double p, std::string t)
			:Fruit(n, c, p),taste(t)
		{}
		void display()const;
		Fruit* getnode();
};
class Orange:public Fruit
{
	friend class Bingtanghulu;
	protected:
		std::string smell;
	public:
		Orange(std::string n, std::string c, double p, std::string s)
			:Fruit(n, c, p),smell(s)
		{}
		void display()const;
		Fruit* getnode();
};
class Apple:public Fruit
{
	friend class Bingtanghulu;
	protected:
		std::string size;
	public:
		Apple(std::string n, std::string c, double p, std::string s)
			:Fruit(n, c, p),size(s)
		{}
		void display()const;
		Fruit* getnode();
};
class Bingtanghulu
{
	private:
		Fruit* head;
	public:
		Bingtanghulu()
		{
			head = new Fruit("tanghulu","red",10.0);
		}
		~Bingtanghulu()
		{
			delete head;
		}
		void Display()const;
		bool Delete(std::string name);
		void Insert(Fruit* fruit);
};
#include<iostream>
#include"variant_list.h"
void Fruit::display()const
{
	std::cout<<"i am a fruit"<<std::endl;
}
void Hawthorn::display()const
{
	std::cout<<"  Hawthorn   "<<std::endl;
}
Fruit* Hawthorn::getnode()
{
	return this;
}

void Orange::display()const
{
	std::cout<<"   Orange"<<std::endl;
}
Fruit* Orange::getnode()
{
	return this;
}
void Apple::display()const
{
	std::cout<<"   Apple"<<std::endl;
}
Fruit* Apple::getnode()
{
	return this;
}
void Bingtanghulu::Display()const
{
	Fruit* hulu = head->link;
	while(hulu)
	{
		std::cout<<"     |     "<<std::endl;
		std::cout<<"     |     "<<std::endl;
		hulu->display();
		hulu = hulu->link;
	}
	std::cout<<"    | |     "<<std::endl;
	std::cout<<"    | |     "<<std::endl;
	std::cout<<"         "<<std::endl;
}
void Bingtanghulu::Insert(Fruit* fruit)
{
	Fruit* hulu = head;
	while(hulu->link)
	{
		hulu = hulu->link;
	}
	hulu->link = fruit->getnode();
	hulu = hulu->link;
	hulu->link = 0;
}
bool Bingtanghulu::Delete(std::string name)
{
	Fruit *hu = head, *lu = head->link;
	while(lu && lu->name != name)
	{
			hu = lu;
			lu = lu->link;
	}
	if(lu)
	{
		hu->link = lu->link;
		return 1;
	}
	else
	{
		return 0;
	}
}
#include"variant_list.h"
int main()
{
	Bingtanghulu tanghulu;
	Hawthorn shanzha("shanzha","red",5.0,"sweet");
	Orange juzi("juzi","yellow",3.0,"sugar");
	Apple pingguo("pingguo","red",5.0,"big");
	std::cout<<"hello world"<<std::endl;
	tanghulu.Insert(&shanzha);
	std::cout<<"hello world"<<std::endl;
	tanghulu.Insert(&juzi);
	tanghulu.Insert(&pingguo);
	tanghulu.Display();
	tanghulu.Delete("juzi");
	tanghulu.Display();
	tanghulu.Delete("pingguo");
	tanghulu.Display();
	tanghulu.Delete("shanzha");
	tanghulu.Display();
	return 0;
}
在此基础上,我们可以将chunk list 进行改进实现一个通用版的variant list,它的原理与冰糖葫芦一样,通过模板类继承一个基类产生统一的接口,通过虚函数实现打印内部数据的多态。需要注意的是模板类的成员函数的实现应在.h文件中。

#include<iostream>
#include<vector>
#include<cstddef>
class Basenode
{
	friend class VariantList;
	protected:
		Basenode* link;
	public:
		Basenode()
			:link(0)
		{}
		~Basenode(){}
		virtual void display()const
		{}
		virtual Basenode* getnode()
		{
			return 0;
		}
};
template<typename T>
class Derivednode:public Basenode
{
	protected:
		std::vector<T> vec;
	public:
	Derivednode(T* buffer, size_t size)
		:vec(buffer, buffer+size)
	{}
	~Derivednode(){};
	void display()const;

	Basenode* getnode();
};
class VariantList
{
	private:
		Basenode* head;
	public:
		VariantList()
		
		{
			head = new Basenode;
		}
		~VariantList()
		{
			delete head;
		}
		void InsertList(Basenode* bnode);
		void DisplayList()const;
};
template<typename T>
void Derivednode<T>::display()const
{
	for(typename std::vector<T>::const_iterator iter = vec.begin();
			iter != vec.end(); ++iter)
	{
		std::cout<<*iter<<"\t";
	}
	std::cout<<std::endl;
}
template<typename T>
Basenode* Derivednode<T>::getnode()
{
	return this;
}
#include"variant_list2.h"
void VariantList::InsertList(Basenode* bnode)
{
	Basenode* p = head;
	while(p->link)
	{
		p = p->link;
	}
	p->link = bnode->getnode();
	p->link->link = 0;
}
void VariantList::DisplayList()const
{
	const Basenode* p = head;
	while(p->link)
	{
		p = p->link;
		p->display();
	}
}
#include"variant_list2.h"
#include<iostream>
int main()
{
	int a[]={1,2,3};
	char b[]={'a','b','c','d'};
	std::string s[]={"hello","world"};
	Derivednode<int> intnode(a, 3);
	Derivednode<char> charnode(b, 4);
	Derivednode<std::string> stringnode(s, 2);
	VariantList vl;
	vl.InsertList(&intnode);
	vl.InsertList(&charnode);
	vl.InsertList(&stringnode);
	vl.DisplayList();
	return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值