C++中實現一個簡單的單向連結串列
最近在linux了一個簡單的單向連結串列,直接上程式碼
連結串列標頭檔案 list.h
#ifndef _LIST_H_
#define _LIST_H_
typedef int T;
template<typename T>
class List
{
private:
struct Node
{
T data;
Node* next;
Node(const T& d=T()):data(d),next(NULL){} //零初始化
};
Node* head;//頭指標,用來儲存頭節點的地址
int len;
public:
List():head(NULL),len(0){}
List(const List& l);
void operator=(const List& l);
~List();
T getElementAtIndex(int index)const;//取得連結串列中指定位置的元素值
List<T>& push_front(const T& d);//前插
List<T>& push_back(const T& d); //尾插
int size()const;//獲取連結串列中節點個數
Node*& getptr(int pos); //在連結串列中找指向指定位置的指標
List<T>& insert(const T& d,int pos); //在任意位置插入
void travel()const; //遍歷
void clear(); //清空連結串列
void erase(int pos); //刪除連結串列中指定位置的元素
int find(const T& d)const; //查詢指定數值的元素在連結串列中出現的位置
void remove(const T& d); //刪除連結串列中指定的元素
void set(int pos,const T& d);
bool empty()const;
const T& front()const;
const T& back()const;
void reverse();//連結串列元素倒置
};
#endif
連結串列實現檔案 list.cpp
#include <iostream>
#include <string>
#include "list.h"
using namespace std;
template<typename T>
List<T>::List(const List<T>& l)
{
len = l.len;
Node* items[len];
for(int i=0;i<len;i++)
{
items[i] = new Node(l.getElementAtIndex(i));
}
for(int i=0;i<len-1;i++)
{
items[i]->next = items[i+1];
}
head = items[0];
}
template<typename T>
void List<T>::operator=(const List<T>& l)
{
clear();
len = l.len;
Node* items[len];
for(int i=0;i<len;i++)
{
items[i] = new Node(l.getElementAtIndex(i));
}
for(int i=0;i<len-1;i++)
{
items[i]->next = items[i+1];
}
head = items[0];
}
template<typename T>
List<T>::~List()
{
clear();
}
//取得連結串列中指定位置的元素值
template<typename T>
T List<T>::getElementAtIndex(int index)const
{
if(index < 0 || index >= len) throw "索引位置越界";
if(index == 0) return head->data;
Node* p = head;
for(int i=1;i<index;i++)
{
p = p->next;
}
return p->next->data;
}
//前插
template<typename T>
List<T>& List<T>::push_front(const T& d)
{
insert(d,0);
return *this;
}
//後插
template<typename T>
List<T>& List<T>::push_back(const T& d)
{
insert(d,len);
return *this;
}
//獲取連結串列中節點個數
template<typename T>
int List<T>::size()const
{
return len;
}
//在連結串列中找指向指定位置的指標
template<typename T>
typename List<T>::Node*& List<T>::getptr(int pos)
{
if(pos < 0 || pos > len) pos = 0;
if(pos == 0) return head;
Node* p = head;
for(int i=1;i<pos;i++)
{
p = p->next;
}
return p->next;
}
//在任意位置插入節點
template<typename T>
List<T>& List<T>::insert(const T& d,int pos)
{
Node*& pn = getptr(pos);
Node* p = new Node(d);
p->next = pn;
pn = p;
++len;
return *this;
}
//遍歷
template<typename T>
void List<T>::travel()const
{
Node* p = head;
while(p)
{
cout << p->data << ' ';
p = p->next;
}
cout << endl;
}
//清空連結串列
template<typename T>
void List<T>::clear()
{
while(head)
{
Node* p = head->next;
delete head;
head = p;
}
len = 0;
}
//刪除連結串列中指定位置的節點
template<typename T>
void List<T>::erase(int pos)
{
if(pos < 0 || pos >= len) return;//有效位置為0~len-1
Node*& pn = getptr(pos);
Node* p = pn;
pn = pn->next;
delete p;
--len;
}
//查詢指定數值的節點在連結串列中出現的位置
template<typename T>
int List<T>::find(const T& d)const
{
Node* p = head;
int pos = 0;
while(p)
{
if(p->data == d)
return pos;
else
p = p->next;
++pos;
}
return -1;
}
//刪除連結串列中指定數值的節點
template<typename T>
void List<T>::remove(const T& d)
{
int pos;
while((pos = find(d))!= -1)
{
erase(pos);
}
}
//修改指定位置的節點資料
template<typename T>
void List<T>::set(int pos,const T& d)
{
if(pos < 0 || pos >= len) return;
getptr(pos)->data = d;
}
//判斷連結串列是否為空
template<typename T>
bool List<T>::empty()const
{
return head == NULL;
}
//取得連結串列中第一個節點資料
template<typename T>
const T& List<T>::front()const
{
if(empty()) throw "空";
return head->data;
}
//取得連結串列中最後一個節點資料
template<typename T>
const T& List<T>::back()const
{
if(empty()) throw "空";
Node* p = head;
while(p->next)
{
p = p->next;
}
return p->data;
}
//將連結串列中的元素倒置
template<typename T>
void List<T>::reverse()
{
if(head == NULL) return;
Node *pre,*cur,*next;
pre = head;
cur = head->next;
while(cur)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
head->next = NULL;
head = pre;
}
template class List<T>; // 顯式例項化
連結串列測試檔案 listTest.cpp
#include <iostream>
#include "list.h"
//typedef int T;
using namespace std;
int main()
{
List<T> l;
List<T> m;
l.push_front(5); //5
l.push_front(8); //8 5
l.push_front(20);// 20 8 5
l.insert(9,2); // 20 8 9 5
l.insert(8,100); //6 20 8 9 5
l.insert(11,-10);//11 6 20 8 9 5
l.insert(9,2);//11 6 1 20 8 9 5
l.push_back(10).push_back(19);//11 8 9 20 8 9 5 10 19
l.travel();
l.reverse();
l.travel();
l.remove(8);
l.remove(9);
l.set(1,33);
l.set(l.find(19),-8);
// cout << l.front() << " " << l.back() << endl;
l.travel(); // 11 33 5 10 -8
// while(!l.empty()) l.erase(0);
// cout << l.size() << endl;
// cout << l.getElementAtIndex(0) << endl;
m.insert(-9,0);
m.insert(13,1);
m.push_front(-5);
m.push_back(2);
cout << "========m連結串列原始值======" << endl;
m.travel();// -5 -9 13 2
m = l;
cout <<"==========將連結串列m中元素倒置==========" << endl;
m.reverse();
m.travel();
cout <<"===========程式結束======" << endl;
return 0;
}