数据结构-单链表 读书笔记

Chain中,数据对象实例的每个元素都放在节点中描述。节点不能被公式进行定位,所以,每个节点中都有与其他节点相关的位置信息。


(盗图了。。。)


可以分别定义Chain和ChainNode类,并将Chain设为ChainNode的友类,使其能够访问ChainNode的所有成员。

单链表类定义
template 
    
    
     
     
class ChainNode {
	friend Chain
     
     
      
      ;  //允许Chain访问私有成员

	private:
		T data;
		ChainNode
      
      
       
        *link;
};

template 
       
       
        
        
class Chain {
	public:
		Chain() {first = 0;}
		~Chain();
		bool IsEmpty() const {return first == 0;}
		int Length() const;
		bool Find(int k, T& x) const; //不修改数据成员 常成员函数
		int Search(const T& x) const;
		Chain
        
        
          & Delete(int k, T& x); Chain 
         
           & Insert(int k, const T& x); void Output(ostream& out) const; //将链表元素送至输出流 private: ChainNode 
          
            *first; //指向第一个节点的指针 }; class OutOfBounds { //定义异常类 public: OutOfBounds() {cout<<"Out of Range!\n";} }; 
           
          
        
       
       
      
      
     
     
    
    


这样就可以用 
Chain<int> Human;
创建一个空的整形单链表。同时,这样不需要指定表的最大长度。

然后,几个函数的实现

普通函数实现
template 
    
    
     
     
Chain
     
     
      
      ::~Chain() {
    //链表的析构函数,用于删除表中的所有节点

	ChainNode
      
      
       
        *next;
	while(first) {
		next = first->link;
		delete first;
		first = next;
	}
}

template 
       
       
        
        
int Chain
        
        
          ::Length() const { //返回链表的长度 ChainNode 
         
           *current = first; int len = 0; while(current) { len++; current = current->link; } return len; } template 
          
            bool Chain 
           
             ::Find(int k, T& x) const { //查找链表中第k个元素,并将其提取到x //查询成功返回true,否则false if(k < 1) return false; //防止错误输入 ChainNode 
            
              *current = first; int index = 1; while(index < k && current) { //防止链表长度不足k current = current->link; index++; } if(current) { x = current->data; return true; } return false; //不存在第k个元素 } template 
             
               int Chain 
              
                ::Search(const T& x) const { //寻找x,如果找到返回x的索引 //查询失败返回0 ChainNode 
               
                 *current = first; int index = 1; //current的索引 while(current && current-> != x) { current = current->link; index++; } if(current) return index; return 0; } template 
                
                  void Chain 
                 
                   ::Output(ostream& out) const { //将链表元素送至输出流 ChainNode 
                  
                    *current; for(current = first; current; current = current->link ) { out< 
                   
                     data<<" "; } } //重载<< template 
                    
                      ostream& operator<<(ostream& out, const Chain 
                     
                       & x) { x.Output(out); return out; } 
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
        
       
       
      
      
     
     
    
    

后面就是删除和插入的函数功能实现

删除插入实现

template 
    
    
     
     
Chain
     
     
      
      & Chain
      
      
       
       ::Delete(int k, T& x) {
    //将第k个元素提取到x,然后删除第k个元素
    //如果不存在,则引发OutOfBounds异常

	if(k < 1 || !first ) throw OutOfBounds();         //不存在第k个元素

	ChainNode
       
       
        
         *p = first;                          //p最终将指向第k个元素

	if(k == 1) first = first->link;                   //p已经指向第k个元素,将其删除
	else {
		ChainNode
        
        
          *q = first; //q最终指向第k-1个元素 for(int index = 1; index < k-1; index++) { q = q->link; if(!q || !q->link) throw OutOfBounds(); //不存在第k个元素 } p = q->link; //存在第k个元素 q->link = p->link; //从链表中删除第k个元素 } //保存第k个元素并释放节点p x = p->data; delete p; return *this; } template 
         
           Chain 
          
            & Chain 
           
             ::Insert(int k, const T& x) { //在第k个元素后插入x //如果不存在第k个元素,则引发异常OutOfBounds if(k<0) throw OutOfBounds(); ChainNode *p = first; //p将指向第k个元素 for(int index = 1; index < k; index++) { p = p->link; if(!p) throw OutOfBounds(); //如果不存在第k个元素,则抛出异常 } ChainNode 
            
              *q = new ChainNode 
             
               ; y->data = x; if(k) { //在p后插入 q->link = p->link; p->link = y; } else { //作为第一个元素插入 q->link = first; first = q; } return *this; } 
              
             
            
           
          
        
       
       
      
      
     
     
    
    


扩展单链表功能
添加清空、归零、尾部添加的功能
首先,清空...易知,析构函数其实可以简单的定义为对clear的调用
Zero实现很简单,建议还是定义为内联函数
push_back的实现,为了达到效率最高,需要借助一个新的成员
ChainNode<T> *last;
同时,需要修改Delete和Insert中分别加入
if(p == last) last = q;

if(!q->link) last = q;

随后便可以正常运行了
template 
    
    
     
     
void Chain
     
     
      
      ::Clear() {
    ChainNode
      
      
       
        *next;
    while(first) {
        next = first->link;
        delete first;
        first = next;
    }
}

template 
       
       
        
        
void Chain
        
        
          ::Zero() {first = 0;} template 
         
           Chain 
          
            & Chain 
           
             ::push_back(const T& x) { ChainNode 
            
              *p; p = new ChainNode 
             
               ; p->data = x; y->link = 0; if(first) { last->link = p; last = p; } else { first = last = y; } return *this; } 
              
             
            
           
          
        
       
       
      
      
     
     
    
    





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值