zoukankan      html  css  js  c++  java
  • 单链表

    一、简单单链表

    先上代码

    Chain.h

    #include<iostream>
    
    template<class T>
    class Chain;
    
    template<class T>
    class ChainNode
    {
    /*
    要将私有成员数据或函数暴露给另一个类,
    必须将后者声明为友元类。
    */
        friend class Chain<T>;
    private:
        T data;
        ChainNode<T>* link;    
    };
    
    template<class T>
    class Chain
    {
    private:
        ChainNode<T>* first;
    /*
    链表长度,即链表元素的个数
    */
        int n;
    public:
        Chain(){first=NULL;n=0;}
        ~Chain();
        bool IsEmpty() const{return first==NULL;}
    /*
    非静态成员函数后面加const(加到非成员函数或静态成员后面会产生编译错误),
    表示成员函数隐含传入的this指针为const指针,
    决定了在该成员函数中,任意修改它所在的类的成员的操作都是不允许的(因为隐含了对this指针的const引用)
    */
        int Length() const{return n;}
        bool Find(int k,T& x) const;
        int Search(const T& x) const;
        bool Delete(int k,T& x);
        bool Insert(int k,const T& x);
        void Output() const;
    };

      

      (1)由于ChainNode用到了友元类Chain;但是类Chain是在ChainNode后面声明的;所以要超前声明类Chain;

          template<class> class Chain
    Chain.cpp

    #include "Chain.h"
    /*
    删除链表中的所有节点
    */
    template<class T>
    Chain<T>::~Chain()
    {
        ChainNode<T>* next;
        while(first)
        {
            next = first->link;
            delete first;
            first = next;
        }
    }
    
    /*
    在链表中查找第k个元素
    k是元素的下标
    */
    template<class T>
    bool Chain<T>::Find(int k,T& x) const
    {
        if(n<1||k<0||k>n-1)
        {
            return false;
        }
        
        ChainNode<T>* current=first;
        for(int j=0;j<k;j++)
        {
            current=current->link;
        }
        x=current->data;
        std::cout<<x<<std::endl;
        return true;
    }
    
    /*
    在链表中搜索
    寻找x,如果发现x,则返回x的地址
    如果x不在链表中,则返回-1
    */
    template<class T>
    int Chain<T>::Search(const T& x) const
    {
        if(n<1)
        {
            return 0;
        }
        ChainNode<T>* current=first;
        for(int j=0;current;j++)
        {
            if(x==current->data)
            {
                std::cout<<j<<std::endl;
                return j;
            }
            current=current->link;
        }
        return -1;
    }
    
    /*
    从链表中删除一个下标为k元素的x
    */
    template<class T>
    bool Chain<T>::Delete(int k,T& x)
    {
        if(n==0||k<0||k>n-1)
        {
            return false;
        }
    
        ChainNode<T>* current=first;
        ChainNode<T>* pre=NULL;
        for(int j=0;j<k-1;j++)
        {
            current=current->link;
        }
        
        if(k==0)
        {
            first=first->link;
        }
        else
        {
            pre=current;
            current=current->link;
            pre->link=current->link;
        }
        x=current->data;
        delete current;
        current=NULL;
        n--;
        return true;
        
    }
    
    /*
    向链表中插入元素
    */
    template<class T>
    /*
    const T& x 
    const在类型T前面,即传入的x不能重新赋值
    */
    bool Chain<T>::Insert(int k,const T& x)
    {
        if(k<0||k>n)
        {
            return false;
        }
    
        ChainNode<T>* current=first;
        ChainNode<T>* p = new ChainNode<T>;
        p->data=x;
        for(int j=0;j<k-1;j++)
        {
            current=current->link;
        }
        if(k>0)
        {
            if(k==n)
            {
                current->link=p;
                p->link=NULL;
            }
            else
            {
                p->link=current->link;
                current->link=p;    
            }
        }
        else 
        {
            p->link=first;
            first = p;
        }
        n++;
        return true;
    }
    
    template<class T>
    void Chain<T>::Output() const
    {
        ChainNode<T>* Node=first;
        while(Node)
        {
            std::cout<<Node->data<<" ";
            Node=Node->link;
        }
        std::cout<<std::endl;
    }
    
    
    int main(void)
    {
        Chain<int> a;
        int e;
        a.Insert(0,10);
        a.Insert(0,11);
        a.Insert(0,15);
        a.Insert(2,12);
        a.Insert(2,14);
        a.Insert(a.Length(),16);
        a.Insert(a.Length(),17);
    //    a.Insert(2,11);
        a.Output();
        a.Delete(0,e);
        a.Delete(a.Length()-1,e);
        a.Delete(2,e);
        a.Output();
        a.Search(10);
        a.Find(2,e);
        return 0;
    }

      

      (1)注意删除和增加元素的时候for循环是for(int j=0;j<k-1;j++);注意是k-1;不同于查找;

        应为删除;增加元素的k;都是以0为下标开始的。

       

    输出

    [ztteng@ztteng Chain]$ ./Chain        
    15 11 14 12 10 16 17 
    11 14 10 16 
    2
    10

    Makefile

    -rwxrw-r--. 1 ztteng ztteng 2428 Oct 22 13:25 Chain.cpp
    -rw-rw-r--. 1 ztteng ztteng  859 Oct 22 11:18 Chain.h
    -rw-rw-r--  1 ztteng ztteng  621 Oct 22 12:35 Makefile
    CC      := g++
    #CCOPT := -g -Wall -O2
    CCOPT := -g -Wall 
    
     
    CURRENT_PATH := $(shell pwd)
    
    INC_PATH := $(CURRENT_PATH)
    #LIB_PATH := $(CURRENT_PATH)/lib
    SRC_PATH := $(CURRENT_PATH)
    OBJS_PATH := $(CURRENT_PATH)
    
    
    
    SRC_FILE_DIR := $(wildcard $(SRC_PATH)/*.cpp) 
    SRC_FILE :=$(notdir $(SRC_FILE_DIR))
    OBJS_FILE := $(SRC_FILE:.cpp=.o)
    
    OBJS:=$(OBJS_PATH)/$(OBJS_FILE)
    
    
     
    TARGET := Chain
    
    $(OBJS_PATH)/%.o:$(SRC_PATH)/%.cpp
        $(CC) $(CCOPT) -I$(INC_PATH) -c $^ -o $@
        
     
    $(TARGET) : $(OBJS)
        $(CC) $(CCOPT) -I$(INC_PATH) -o $@ $^
    
    
    .PHONY : clean
    clean : 
        rm -rf $(TARGET)
        rm -rf $(OBJS)

      (1)makefile当时报错;

     Makefile:25: *** missing separator.  Stop.

     原因是从博客园复制下来的makefile不可用;是因为 命令必须以tab开头;而复制下来的命令不是tab开头所以报没有分割错误

  • 相关阅读:
    【知了堂学习笔记】java 正则表达式
    【知了堂学习笔记】java 接口与抽象类
    【知了堂学习笔记】java web 简单的登录
    【知了堂学习笔记】java IO流归纳总结
    【知了堂学习笔记】java 自定义异常
    【知了堂学习笔记】java 方法重载与重写的归纳
    编译链接符号重定位流程简述
    项目用到了lua的哪些部分
    lua协程实现简析
    杂乱无章
  • 原文地址:https://www.cnblogs.com/ztteng/p/3382252.html
Copyright © 2011-2022 走看看