线性表——线性表+抽象链表类+单向链表讲解

1.讲解:

线性表两种分类:
顺序表,链表
线性表>记录(数据元素)>数据项

顺序表:只有唯一一个节点只存在一个后继,不存在前驱,只有唯一一个节点存在前驱,不存在后继,中间所有的节点都存在位移的前驱和后继
顺序表的优点:可以随机存取,方便访问,存储密度大,空间利用率高
顺序表缺点:难以实现插入数据的操作,而且空间一旦定义就会固定,不能动态控制空间内存的大小

链表的缺点:不能随机存取,空间访问麻烦指针域会占用部分内存空间,
链表优点:可以方便实现数据节点的插入

顺序存储类就不过多讲解了
链式存储类中我们来实现一下抽象链表类

节点对象<抽象链表对象<单链表对象

2.代码:

#include"iostream"
#include"cstdio"
#include"cstring"
#include"cstdlib"

using namespace std;

template<typename T>    
class listnode
{
	public:
		listnode()
		{
			next=NULL;
		}
		listnode(T item,listnode<T>* another)
		{
			data=item;
			next=another;
		}
		T data;
		listnode<T>* next;
};

template<typename T>
class ablist
{
	public:
		ablist()
		{
			head=NULL;
			length=0;
		}
		ablist(ablist<T>& a)  //注意这里必须是引用,因为涉及到指针,不用引用的话,不会完整的复制过来 
		{
			head=NULL;
			length=0;
			listnode<T>* p=head;
			listnode<T>* help=a.head;
			while(help!=NULL)
			{
				p=new listnode<T>(help->data,NULL);
				p=p->next;
				help=help.next;
			}
		}
		~ablist()
		{
			listnode<T>* p=head->next;
			while(head->next!=NULL)
			{
				head->next=head->next->next;
				free(p);
				p=head->next;
			}
			free(head);
		}
		listnode<T>* gethead()
		{
			return head;
		}
		listnode<T>* getnext(listnode<T>& n)
		{
			return n.next; 
		}
		T getnumber(int i)  //取出第i个元素 
		{
			listnode<T>* p=head;
			for(int j=1;j<i;j++) p=p->next;
			return p->data;
		}
		bool setnumber(T k,int i)
		{
			listnode<T>* p=head;
			for(int j=1;j<i;j++)
			{
				if(p==NULL) return false;
				p=p->next;
			}
			p->data=k;
			return true;
		}
		listnode<T>* find(int i)
		{
			listnode<T>* p=head;
			for(int j=1;j<i;j++)
			{
				if(p==NULL) return NULL;
				p=p->next;
			}
			return p;
		}
		listnode<T>* find1(T num)
		{
			listnode<T>* p=head;
			while(p!=NULL)
			{
				if(p->data==num) return p;
				p=p->next;
			}
			return NULL;
		}
		void listempty()
		{
			listnode<T>* p=head->next;
			while(head->next!=NULL)
			{
				head->next=head->next->next;
				free(p);
				p=head->next;
			}
			free(head);
			head=NULL;
			length=0;
		}
		int returnlength()
		{
			return length;
		} 
		virtual bool insert(T,int)=0;
		virtual bool delete_(int)=0;
		virtual bool remove(T)=0;
	protected:
		listnode<T>* head;   //这一点可以学习一下,都定义成模板,通过外包类模板模范子类的模板
		int length; 
};

template<typename T>
class singlelist:public ablist<T>   //万分小心,学习一下,在模板类继承的时候,我们的因为偏特化的存在,必须要用this才可以看到父类成员 
{
	public:
    	singlelist()
		{}
    	bool insert(T num,int i)
    	{
    		if(i==0) 
    		{
    		    this->head=new listnode<T>(num,NULL);
    			this->length++;
    			return true;
    		}
    		i++;
    		listnode<T>* p=this->find(i-1);
    		if(p==NULL) return false;
    		listnode<T>* help=new listnode<T>(num,NULL);
    		help->next=p->next;
    		p->next=help;
    		this->length++;
    		return true;
    	}
     	bool delete_(int i)
    	{
    		listnode<T>* p=this->find(i-1);
    		if(p==NULL||p->next==NULL) return false;
    		else
    		{
    			listnode<T>* help=p->next;
     			T num=p->next->data;
    			p->next=p->next->next;
       			free(help);
       			this->length--;
    			return true;
    		}
    	}
    	bool remove(T num)
    	{
    		listnode<T>* help=NULL;
    		listnode<T>* p=this->head;
    		while(p!=NULL)
    		{
    			if(p->data==num) break;
    			else help=p;
	    		p=p->next;
    		}
     		if(p==NULL) return false;
    		help->next=help->next->next;
    		free(p);
    		this->length--;
    		return true;
    	}
    	void print()
		{
			listnode<T>* p=this->head;
			while(p!=NULL)
			{
				cout<<p->data<<' ';
				p=p->next;
			} 
			cout<<endl;
		} 
};

int main()
{
	singlelist<int> my;
	my.insert(1,my.returnlength());
	my.insert(2,my.returnlength());
	my.insert(4,my.returnlength());
	my.insert(7,my.returnlength());
	my.insert(3,my.returnlength());
	my.insert(8,my.returnlength());
	my.insert(9,my.returnlength());
	my.print();
	my.delete_(5);
	my.print();
	my.remove(8);
	my.print();
	return 0;
} 


3.应用:单链表进行加法运算:

#include"iostream"
#include"cstdlib"
#include"cstdio"

using namespace std;

class point
{
	public:
		point(int n,int m):ceof(n),exp(m){
			next=NULL;
		}
		friend ostream& operator<<(ostream& out,point& p)
		{
			printf("%+dx^%d",p.ceof,p.exp);
		}
		int getceof()
		{
			return ceof;
		}
		int getexp()
		{
			return exp;
		}
		point* next;
	private:
		int ceof;
		int exp;
};

class singlelist
{
	public:
		singlelist()
		{
			head=new point(0,0);
			head->next=NULL;
			num=0;
		}
		void insert(int ceof,int exp)
		{
			point* p=new point(ceof,exp);
			point* help=head;
			while(help->next!=NULL&&help->next->getexp()>=p->getexp()) help=help->next;
			p->next=help->next;
			help->next=p;
			num++;
		}
		void add(singlelist& a,singlelist& b)
		{
			point* heada=a.head->next;
			point* headb=b.head->next;
			point* headc;
			point* help=head;
			while(heada!=NULL&&headb!=NULL)
			{
				if(heada->getexp()==headb->getexp()) 
				{
					headc=new point(heada->getceof()+headb->getceof(),heada->getexp());
					heada=heada->next;
					headb=headb->next;
				}
				else
				{
					if(heada->getexp()<headb->getexp()) 
					{
						headc=new point(headb->getceof(),headb->getexp());
						headb=headb->next;
					}
					else 
					{
						headc=new point(heada->getceof(),heada->getexp());
						heada=heada->next;
					}
				} 
				help->next=headc;
				help=help->next;
				headc=headc->next;
			} 
			if(heada==NULL)
			{
				while(headb!=NULL)
				{
					headc=new point(headb->getceof(),headb->getexp());
					headc=headc->next;
					headb=headb->next;
				}
			} 
			else
			{
				while(heada!=NULL)
				{
					headc=new point(heada->getceof(),heada->getexp());
					headc=headc->next;
					heada=heada->next;
				}
			}
		}
		void print()
		{
			point* p=head->next;
			while(p!=NULL)
			{
				if(p->getceof()!=0) cout<<*p;
				p=p->next;
			}
		}
	private:
		point* head;
		int num;
};

int main()
{
	singlelist a;
	singlelist b;
	singlelist c;
	a.insert(4,21);
	a.insert(5,10);
	a.insert(7,4);
	a.insert(1,1);
	b.insert(5,12);
	b.insert(-5,10);
	b.insert(11,4);
	b.insert(1,1);
	c.add(a,b);
	c.print();
	return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值