链表常用操作的实现-C++模板实现
来源:互联网 发布:阿里云redis 怎么使用 编辑:程序博客网 时间:2024/05/17 02:35
注:该贴为本人在温习数据结构的过程中自娱自乐编写的代码,如有错误欢迎纠正:)
链表节点声明
template <class T>class LinkNode{public: LinkNode(T v) { value=v; } T value; LinkNode<T>* next;};
链表类的声明
template <class T>class LinkList{ public: LinkList(); LinkList(const LinkList& list); virtual ~LinkList(); void clear(); int length() const; bool is_empty() const; LinkNode<T>* push_back(T value); LinkNode<T>* insert(T value, int pos); LinkNode<T>* remove(T value); LinkNode<T>* find(T value) const; //查找链表的中间节点 LinkNode<T>* find_middle() const; //查找链表的倒数第N个节点 LinkNode<T>* find_reverse_nth(int n) const; //链表反转 LinkList<T>& reverse(); //在链表中创建环,n表示交点相对于头节点的位置 LinkNode<T>* make_cycle(int n); //在链表中解除环,cycle_entry表示环的入口点 void LinkList<T>::clear_cycle(LinkNode<T>* cycle_entry); //检查链表是否有环 LinkNode<T>* check_cycle() const; //检查链表环的入口节点 LinkNode<T>* find_cycle_entry() const; //合并两个链表,假设两个链表都已经排序 template<class U> //这里这样定义才能编译通过,具体问题参见http://blog.csdn.net/dongzhongshu/article/details/6200466 friend LinkList<U>& mergelist(const LinkList<U>& list1, const LinkList<U>& list2); //链表冒泡排序 LinkList<T>& bubble_sort(); //链表选择排序 LinkList<T>& select_sort(); void output() const; private: LinkNode<T>* head;};
构造函数和析构函数
template <class T>LinkList<T>::LinkList(){ this->head=NULL; T tmp; LinkNode<T> *r, *p=this->head; cin >> tmp; while(tmp != MIN_INT) //此处先争对int型,以后再修改 { r=new LinkNode<T>(tmp); r->next=NULL; if(head==NULL) head=r; else p->next=r; p=r; cin >> tmp; }}template <class T>LinkList<T>::LinkList(const LinkList& list){ LinkNode<T> *p=list.head; LinkNode<T> *q=NULL, *r=NULL; head=NULL; while(p!=NULL) { r=new LinkNode<T>(p->value); r->next=NULL; if(head==NULL) { head=r; } if(q!=NULL) { q->next=r; } q=r; p=p->next; }}template <class T>void LinkList<T>::clear(){ LinkNode<T>* p=this->head; while(head!=NULL) { head=head->next; p->next=NULL; delete p; p=head; }}
template <class T>LinkList<T>::~LinkList(){ clear();}
检查链表是否为空
template <class T>bool LinkList<T>::is_empty() const{ return head==NULL;}template <class T>
链表的长度
int LinkList<T>::length() const{ int size=0; LinkNode<T>* p=head; while(p!=NULL) { size++; p=p->next; } return size;}
链表的插入和删除
template <class T>LinkNode<T>* LinkList<T>::push_back(T value){ LinkNode<T>* p=head,q; while(p!=NULL && p->next!=NULL) p=p->next; q=new LinkNode<T>(value); q->next=NULL; if(p!=NULL) p->next=q; else head=q; return q;}template <class T>LinkNode<T>* LinkList<T>::insert(T value, int pos){ LinkNode<T>* p=head, q=p, r; for(int i=0; i<pos && p!=NULL; i++) { q=p; p=p->next; } r=new LinkNode<T>(value); if(!q) head=r; else q->next=r; r->next=p; return r;}template <class T>LinkNode<T>* LinkList<T>::remove(T value){ LinkNode<T>* p=head, q; while(p) { if(p->value==value) { if(q) { q->next=p->next; } p->next=NULL; delete p; } q=p; p=p->next; }}
查找,包括普通查找,查找中间节点以及查找倒数第N个节点
关于后面两个查找的原理请参考链表笔试面试题
template <class T>LinkNode<T>* LinkList<T>::find(T value) const{ LinkNode<T>* p=head; while(p) { if(p->value==value) return p; p=p->next; } return NULL;}template <class T>LinkNode<T>* LinkList<T>::find_middle() const{ LinkNode<T>* p=head,*q=head; while(q!=NULL) { if(q->next!=NULL) q=q->next->next; else break; p=p->next; } return p;}template <class T>LinkNode<T>* LinkList<T>::find_reverse_nth(int n) const{ if(n>length()) return NULL; LinkNode<T> *p=head,*q=head; for(int i=0; i<n; i++) { if(p!=NULL) p=p->next; else return NULL; } while(p!=NULL) { p=p->next; q=q->next; } return q;}
链表倒转
template <class T>LinkList<T>& LinkList<T>::reverse(){ LinkNode<T> *p=head,*q=NULL,*r=NULL; if(p!=NULL) q=p->next; while(q!=NULL) { r=q->next; q->next=p; p=q; q=r; } head->next=NULL; head=p; return *this;}template <class T>LinkNode<T>* LinkList<T>::_reverse(LinkNode<T>* pNode){ if(pNode==NULL) return NULL; else if(pNode->next==NULL)}
去除链表中存在的环
template <class T>void LinkList<T>::clear_cycle(LinkNode<T>* cycle_entry){ LinkNode<T>*q=cycle_entry; while(q->next!=cycle_entry) q=q->next; q->next=NULL;}
检查链表中是否有环
template <class T>LinkNode<T>* LinkList<T>::check_cycle() const{ LinkNode<T> *p=head, *q=(head==NULL)?NULL:p->next; while(p!=q) { if(p) p=p->next; else break; if(q) q=q->next; else break; if(q) q=q->next; else break; } if(!p || !q) return NULL; return p;}
查找链表中环的入口节点
template <class T>LinkNode<T>* LinkList<T>::find_cycle_entry() const{ LinkNode<T>* jointNode=check_cycle(); if(jointNode==NULL) return NULL; LinkNode<T>* p=jointNode->next; LinkNode<T>* q=head; while(p!=q) { p=p->next; q=q->next; } return p;}
合并两个有序列表
template <class T>LinkList<T>& mergelist(const LinkList<T>& list1, const LinkList<T>& list2){ LinkList<T>* pNewList; if(list1.is_empty()) { pNewList=new LinkList<T>(list2); return *pNewList; } pNewList=new LinkList<T>(list1); if(list2.is_empty()) return *pNewList; LinkNode<T> *p=pNewList->head, *q, *r=list2.head, *s; while(r) { if(p && p->value<=r->value) { q=p; p=p->next; } else { s=new LinkNode<T>(r->value); q->next=s; s->next=p; q=s; r=r->next; } } return *pNewList;}
链表的插入排序和选择排序
template <class T>LinkList<T>& LinkList<T>::bubble_sort(){ LinkNode<T> *p,*q; for(p=head;p;p=p->next) //这个循环只是为了让循环达到和链表中节点相等的个数,p不会被实际用到 for(q=head;q->next;q=q->next) { if(q->value>q->next->value) { T tmp=q->value; q->value=q->next->value; q->next->value=tmp; } }}template <class T>LinkList<T>& LinkList<T>::select_sort(){ LinkNode<T> *p=head,*q, *smallest; for(;p;p=p->next) { smallest=p; for(q=p->next;q;q=q->next) { if(q->value<smallest->value) smallest=q; } if(smallest!=p) { T tmp=smallest->value; smallest->value=p->value; p->value=tmp; } } return *this;}
链表的输出
template <class T>void LinkList<T>::output() const{ LinkNode<T>* p=head; while(p) { cout << p->value << " "; p=p->next; } cout << endl;}
- 链表常用操作的实现-C++模板实现
- 单向链表的常用操作(C++模板实现)
- 链表的常用操作(java实现)
- C++:操作单向链表的实现
- 链表的实现与操作(C语言实现)
- 静态链表的实现与操作(C语言实现)
- 循环链表的实现与操作(C语言实现)
- 双向链表的实现与操作(C语言实现)
- 【C++】模板实现带头节点的双向循环链表
- [数据结构]链表的实现(c++/类模板)
- [c++]栈模板的实现
- [C++] 模板类实现简单链表
- C实现链表操作
- C语言字符串操作函数及常用的实现
- 链表的模板实现
- 链表的模板实现
- //链表的模板实现
- 顺序链表的常用操作实现及注意事项
- 2011斯坦福大学iOS应用开发教程学习笔记(第三课)Objective-C
- const 指针与指向const的指针
- POJ 2243 Knight Moves【A*算法入门演练】
- 链式栈类定义
- GCC -lm 是什么意思
- 链表常用操作的实现-C++模板实现
- 面向对象中实例建立,为什么不能直接在类里创建对象
- 从走到跑 王秀娟的坚守
- OCP-1Z0-053-V12.02-269题
- NSLog 输出格式
- shell编程基础之认识与学习BASH
- mysql使用过程中,为防止出现中文乱码需要注意的四个方面
- 单链表反转
- 分享一个shell for循环+case的脚本(监控程序状态)