数据结构——链表

工作之后很少再从头开始实现基础数据结构,最近试着写一写,发现还是有很多知识只能在写的过程中才能去体会,而不是想当然的认为造个轮子就是依葫芦画瓢了。一些细节上的处理,不管是数据结构本身的知识点,还是语言语法本身的知识点同样也只能在写的过程中才能更好的理解和把握。

废话不多说,C++实现一个list模板。

数据结构最重要的四个特征:增、删、查、改。这里没有实现改的api,主要是因为对于list而言,“改”并不是很重要。

#include<iostream>
#include<errno.h>
#include<typeinfo>
#include<exception>
#include<cctype>
#include<unistd.h>

template<typename T>
struct node
{
   T data;
   struct node* next;
};

template<typename T>
class List
{
private:
   struct node<T>* head;
   struct node<T>* last;
   struct node<T>* tmp;
public:
   explicit List(){
	this->head = NULL;
   }
   ~List(){
	destroy_list();	
   }
private:
   void init_list(const T& d){
	this->head = new node<T>;
	this->head->data = d;
	this->head->next = NULL;
	this->tmp = this->head;
	this->last = head;
   }
   node<T>* get_head(){
	return this->head;
   }
   void destroy_list(){
	this->tmp = this->head;
	struct node<T>* tmp_node = tmp;
	while(this->tmp){
	   tmp_node = this->tmp->next;
	   delete this->tmp;
	   this->tmp = tmp_node;
	}
   }
public:
   bool is_empty(){
	return this->head?false:true;	
   }

   bool is_exist(const T& d){
	bool is_ = false;
	struct node<T>* node = find_node(d);
	node? is_ = true: is_ = false;
	return is_;
   }

   void push_back_node(const T& d){
	if(typeid(d) != typeid(int)) throw std::exception::exception("type is not correct!");
	if(this->head){
	   this->tmp = new node<T>;
	   this->tmp->data = d;
	   this->tmp->next = NULL;
	   this->last->next = tmp;
	   this->last = this->tmp; 	   
	}	
	else{
	   init_list(d);
	}
   }

   void pop_back_node(){
	struct node<T>* tmp_node = this->head;
	if(this->is_empty()) return;
	
	while(tmp_node->next != this->last){
		std::cout<<" tmp = "<<tmp_node->data<<std::endl<<std::flush;
		tmp_node  = tmp_node->next;
	}

	if(!this->last) throw std::exception::exception("Oops,something wrong!");
	
	//caution tmp_node->next must be set NULL before delete this->last, because tmp_node->next is the same as this->last
	tmp_node->next = NULL;
	delete this->last;
	this->last = tmp_node;
   }

   void display_node(){
	int i = 0;
	this->tmp = this->head;
	while(this->tmp){
	   std::cout<<"node "<<i++<<" = "<<this->tmp->data<<std::endl;
	   this->tmp = this->tmp->next;
	}
   }

   void delete_node(const T& d){
	struct node<T>* priv_node;
	struct node<T> * tmp_node;
	struct node<T> * next_node;
	if(!is_exist(d)) return;
	if(this->head->data == d){
	   if(!this->head->next){
	   	delete this->head;
	   	this->head = NULL;
	   	this->tmp = NULL;
	   	this->last = NULL;
	     return;
	   }
	   else{
		this->tmp = this->head->next;
		delete this->head;
		this->head = this->tmp;
		this->tmp = this->head;		
	     return;
	   }
	}
	priv_node = find_priv_node(d);
	if(!priv_node) return;
	tmp_node = priv_node->next;
	if(!tmp_node) throw std::exception::exception("Oops,something wrong!");
	next_node = tmp_node->next;
	priv_node->next = next_node;
	delete tmp_node;

	return;
   }

   size_t get_size(){
	size_t size = 0;
	this->tmp = this->head;
	while(tmp){ 
	   tmp = tmp->next;
	   size++;
	}
     return size;
   }

private:
   struct node<T>* find_node(const T& d){
	this->tmp = this->head;
	while(this->tmp){
	   if(this->tmp->data == d) return tmp;
	   else this->tmp = this->tmp->next;
	}
     return NULL;
   }

   struct node<T>* find_priv_node(const T& d){
	struct node<T>* front_node = this->head;
	struct node<T>* rear_node = this->head;
	if(front_node->data == d) return NULL;
	while(rear_node->next){
	   front_node = rear_node;
	   rear_node = rear_node->next;
	   if(rear_node->data == d) return front_node;
	}
     return NULL;
   }

};

int main()
{
   std::cout<<"---start----"<<std::endl;

   List<int> l;
   l.push_back_node(3);
   l.push_back_node(4);
   l.push_back_node(5);
   l.push_back_node(6);
   l.push_back_node(7);
   l.push_back_node(8);
   l.display_node();

   std::cout<<" 4 is exist ? --> "<<l.is_exist(4)<<std::endl;
   std::cout<<" 9 is exist ? --> "<<l.is_exist(9)<<std::endl;
   std::cout<<" size = "<<l.get_size()<<std::endl;

   l.delete_node(6);
   l.display_node();
   std::cout<<"---------------"<<std::endl;
   l.delete_node(3);

   l.display_node();

   std::cout<<"---------------"<<std::endl;
  
   l.push_back_node(100);
   l.push_back_node(200);
   l.push_back_node(100);

   l.display_node();
   std::cout<<"---------------"<<std::endl;

   l.delete_node(100);
   l.display_node();
   std::cout<<"---------------"<<std::endl;
   l.delete_node(100);
   l.display_node();
   std::cout<<"---------------"<<std::endl;

   List<std::string> l1;

   l1.push_back_node("xujiwei");
   l1.push_back_node("hello");
   l1.push_back_node("world");
   l1.display_node();

   l1.delete_node("xujiwei");
   l1.display_node();
   l1.pop_back_node();
   l1.display_node();

return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值