一、简单单链表
先上代码
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开头所以报没有分割错误