EE屌丝的数据结构笔记(二)

本来链表的文件早写好了,无奈老师一道链表倒置的题着实伤了下脑筋,使用标准思路却忘了我设置了头节点,一个小细节导致程序老是处于崩溃状态,一番调试后终于调试成功,故在此分享下想关心得。

Link类头文件

#ifndef LINK_H_
#define LINK_H_
#include<iostream>
template<class Elem>
class Link 
{
	public:
		Elem element;
		Link* next;
		Link(const Elem& elemval, Link* nextval = NULL)
		{
			element = elemval;
			next = nextval;
		}
		Link(Link* nextval = NULL)
		{
			next = nextval;
		} 
};
#endif

link类方法实现

#include"acctlist.h"
#include<iostream>
#include"Link.h"
using namespace std;


template<class Elem>
class Llist: public List<Elem>{
	private:
		Link<Elem> *head;
		Link<Elem> *tail;
		Link<Elem> *fence;
		int leftcnt,rightcnt;
	
		void init()
		{
			fence = head = tail = new Link<Elem>;
			leftcnt = rightcnt = 0;
		}
	
		void removeall()
		{
			while(head != NULL)
			{
				fence = head;
				head= head -> next;
				delete fence;
			}
		}
	public:
		Llist(int size)
		{
			init();
		}
		
		~Llist()
		{
			removeall();
		}
		
		void clear()
		{
			removeall();
			init();	
		}
		
		bool insert(const Elem& item)
		{
			fence -> next = new Link<Elem>(item,fence -> next);
			if(tail == fence)
				tail = fence ->next;
			rightcnt++;
			return true;
		}
		bool append(const Elem& item)
		{
			tail = tail -> next = new Link<Elem>(item,NULL);
			rightcnt++;
			return true;
		}
		bool remove(Elem& it)
		{
			if(fence -> next == NULL)
				return false;
			it = fence -> next -> element;
			Link<Elem> *Itemp = fence -> next;
			fence -> next = Itemp ->next;
			if(tail == Itemp)
				tail = fence;
			delete Itemp;
			rightcnt--;
			return true;
		}
		
		void setStart()
		{
			fence = head; 
			rightcnt += leftcnt;
			leftcnt = 0;
		}
		
		void setEnd()
		{
			fence = tail;
			leftcnt += rightcnt;
			rightcnt = 0;
		}
		
		void prev()
		{
			Link<Elem> *temp = head;
			if(fence == head)
				return ;
			while(temp -> next != fence)
				temp = temp -> next;
			fence = temp;
			leftcnt--;
			rightcnt++;
		}
		
		void next()
		{
			if( fence != tail)
			{
				fence = fence -> next;
				rightcnt--;
				leftcnt++;
			}
		}
		
		int leftLength() const
		{
			return leftcnt;
		}
		
		int rightLength() const
		{
			return rightcnt;
		}
		
		bool setPos(int pos)
		{
			if((pos<0) || (pos > (rightcnt+leftcnt)))
				return false;
			setStart();
			for(int i = 0;i<pos;i++)
				next();
			return true;
			
		}
		bool getValue(Elem & it) const
		{
			if(rightLength() == 0)
				return false;
			it = fence -> next -> element;
			return true;
		}
		
		void reverse() 
		{
			cout << "Now begin the reverse the list" << endl; 

			if(head -> next && head -> next -> next) {//不为空表或者单节点 
				Link<Elem>*				p = head -> next;
				Link<Elem>*				r = head -> next -> next;
				Link<Elem>*                             temp = p;
				p -> next = NULL; 
				tail = p ;
				
				while(r) {
					p = r ;
					r = r -> next ;
					p -> next = temp ;
					temp = p ;
			}
			head -> next = temp ;
		}
			
		}
		void print() const
		{
			Link<Elem>* temp = head;
			cout << " < ";
			while(temp != fence)
			{
				cout << temp -> next -> element << " ";
				temp = temp -> next;
			}
			cout << " | ";
			while(temp -> next != NULL )
			{
				cout << temp -> next -> element <<" ";
				temp = temp -> next;
			}
			cout << ">\n";
		}
};
这个头文件中仍然写了很多内联函数,供学习调试方便,以后仍然会按照常规的方法重写。同时大家可以看到reverse()这个函数的代码风格和其他的函数不一样,的确,这个函数是我后来添加的,使用了DOOM3的源码当中的变量声明风格与紧凑的写法,虽然当前感觉有些不伦不类,不过还在继续思考如何写的更好看,以便写出简易易懂的代码方便自己调试。同时在写reverse函数的时候原本以为两个link指针即可搞定,结果忽略了我使用的不带参数的头节点,结构第一次测试逆置功能的时候缺失了首尾元素,所以还是使用了三个link指针才搞定。

测试代码

#include<iostream>
#include"list_link.h"
using namespace std;
enum{clear,insert,append,remove11,setStart,setEnd,prev,next,leftLength,rightLength,
setPos,reverse};

int main()
{
	int				op;
	int             temp;
	Llist<int>  	L1(10);
	
	cout << "Please entert the op code" << endl;
	cout << "0.clear" << endl;
	cout <<	"1.insert" << endl;
	cout <<	"2.append" << endl;
	cout << "3.remove" << endl;
	cout <<	"4.setStart" << endl;
	cout <<	"5.setEnd" << endl;
	cout <<	"6.prev" << endl;
	cout <<	"7.next" << endl;
	cout <<	"8.leftLength" << endl;
	cout <<	"9.rightLength" << endl;
	cout <<	"10.setPos" << endl;
	cout <<	"11.reverse" << endl;
	
	cout << "Please enter the op code(12 to quit)" << endl;
	cin >> op ;
	while( op != 12 ) {
		switch( op ) {
			case clear: L1.clear();
				   		L1.print();
				   		break;
				   
			case insert: cout << "please enter the number you want to insert:" << endl ;
				   	     cin >> temp ;
				         L1.insert(temp) ;
				         L1.print() ;
				         break;
				   
			case append: cout << "Please enter the number you want to append:" << endl ;
				   		 cin >> temp ;
				         L1.append(temp) ;
				         L1.print() ;
				         break;
				   
			case remove11: cout << "Now the list has been removed  " << endl ;
				           L1.remove(temp);
				           L1.print();
				           break;
				   
			case setStart: cout << "Now set the start " << endl ; 
				           L1.setStart() ;
				           L1.print() ;
				           break;
				   
			case setEnd: cout << "Now set the end " << endl ;
				         L1.setEnd() ;
				         L1.print() ;
				         break;
				   
			case prev: cout << "check the prev " << endl ; 
				       L1.prev() ;
				       L1.print() ;
				       break;
				   
			case next: cout << "check the next " << endl ;
				       L1.next() ;
				       L1.print() ;
				       break;
				   
			case leftLength: cout << "Now the leftLength is " <<
				             L1.leftLength() << endl ;
				             break;
			case rightLength: cout << "Now the rightLength is " <<
				              L1.rightLength() << endl ;
				              break;
			case setPos: cout << "set the pos is "<< endl ;
				         L1.setPos(3) ;
				         L1.print() ;
				         break;
			case reverse: cout << "Now reverse " << endl ;
				          L1.reverse() ;
				          L1.print() ;
				          break;
		}
		cout<<"Please enter the op code:";
		cin >> op;
	}
	cout << "thanks for using" << endl ;
	
}

这次的测试代码稍微人性化了一点点,复制粘贴后的代码排列略乱,我就没有调了,毕竟这样的测试代码以后会很少写了。

测试结果



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值