1、【資料結構】線性結構之單鏈表
阿新 • • 發佈:2018-12-17
單向連結串列
一、定義:
單向連結串列(單鏈表)時連結串列的一種,它由節點組成,每個節點都包含下一個節點的指標。
單鏈表的特點是:節點的連結方向是單向的;相對於陣列來說,單鏈表的的隨機訪問速度較慢,但是單鏈表刪除/新增資料的效率很高。
二、實現:
單鏈表的實現方式有很多種,常見的有
(1)帶頭結點的單鏈表
(2)不帶頭結點的單鏈表
(3)帶頭節點和尾節點的單鏈表
(1)和(2)的主要區別是:
(1)的頭節點是個空節點,其主要作用是指向連結串列的第一個節點, (2)的頭結點不是空節點,是整個連結串列的第一個節點。
(3)是一個迴圈連結串列,即連結串列的尾節點指向頭結點;下面會對各種實現方式進行具體的介紹。
三、實現
(1)帶頭結點的單鏈表的C++實現
SList.h
typedef int Type; //定義節點類 struct Node { Node(const Type x); Type data; Node *next; }; class SList { public: SList();//建構函式 SList(const SList&s);//拷貝建構函式 SList &operator=(SList &s);//賦值運算子過載 ~SList();//解構函式 public: //單鏈表的具體操作 bool isEmpty(); int length(); void reverseList();//逆置 void printList();//列印連結串列 void Clear(); //void sortList();//排序 void pushBack(const Type &data);//在尾部插入一個節點 void popBack();//刪除尾節點 void pushFront(Type data);//頭插 void popFront();//刪除頭節點 private: Node *head; int len;//連結串列長度 };
SList.cpp
#include <iostream> #include "SList.h" using namespace std; //節點類的建構函式 Node::Node(const Type x) :data(x),next(NULL) { } //建構函式 SList::SList() :head(NULL),len(0) { head = new Node(NULL); head->next = NULL; } //拷貝建構函式 SList::SList(const SList &s) { head->next = NULL; len = s.len; Node *current; //自己連結串列的尾部元素 Node *sCurrent = s.head->next;//s的第一個元素 while(sCurrent != NULL) { for(int i = 1; i <= s.len; i++) { Node *newNode = new Node(sCurrent->data); if(i == 1) { head->next = newNode; current = head->next; } else { current->next = newNode; current = current->next; } sCurrent = sCurrent->next; } } } //賦值運算子過載 SList& SList::operator=(SList &s)//推薦寫法 { if(this != &s) { swap(head, s.head); } return *this; } //解構函式 SList::~SList() { Clear(); } //清空連結串列 void SList::Clear() { Node *current = NULL; Node *p = head->next; while(p != NULL) { current = p->next; delete p; p = current; } delete current; current = NULL; delete head; p = NULL; len = 0; } //連結串列尾部插入 void SList::pushBack(const Type &data) { if(head->next == NULL) { head->next = new Node(data); len++; } else { Node *p = head->next; while(p->next != NULL) { p = p->next; } p->next = new Node(data); len++; p = NULL; } } //連結串列尾部刪除 void SList::popBack() { if(head->next == NULL) cout << "this SList is empty." << endl; else { Node *current; Node *p = head->next; for(int i = 1; i < len-1; i++) { p = p->next; } current = p->next; p->next = current->next; delete current; current = NULL; len--; } } void SList::printList() { if(head->next == NULL) cout << "this SList is empty." << endl; else { Node *temp = head->next; while(temp != NULL) { cout << temp->data << " "; temp = temp->next; } cout << endl; delete temp; temp = NULL; } } //判斷連結串列是否為空 bool SList::isEmpty() { if(head->next == NULL) return true; else return false; } //獲取連結串列長度 int SList::length() { return len; } //連結串列逆置 void SList::reverseList() { Node *temp = head->next; head->next = NULL; if(temp == NULL) cout << "this SList is empty." << endl; else { while(temp != NULL) { Node *p = temp->next; temp->next = head->next; head->next = temp; temp = p; } } } void SList::pushFront(Type data) { if(head->next == NULL) head->next = new Node(data); else { Node *temp = new Node(data); temp->next = head->next; head->next = temp; } } void SList::popFront() { if(head->next == NULL) cout << "this SList is empty." << endl; else { Node *temp = head->next; head->next = temp->next; delete temp; } }
main.cpp
#include <iostream>
#include "SList.h"
using namespace std;
int main()
{
SList mylist;
mylist.pushBack(1);
mylist.pushBack(2);
mylist.pushBack(3);
mylist.printList();
mylist.popBack();
mylist.printList();
mylist.reverseList();
mylist.printList();
mylist.pushFront(5);
mylist.printList();
mylist.popFront();
mylist.printList();
return 0;
}
C++實現單鏈表(不帶頭結點) SList.h
typedef int Type;
//定義節點類
struct Node
{
Node(const Type x);
Type data;
Node *next;
};
class SList
{
public:
SList();//建構函式
SList(const SList&s);//拷貝建構函式
SList &operator=(SList &s);//賦值運算子過載
~SList();//解構函式
public:
//單鏈表的具體操作
bool isEmpty();
int length();
void reverseList();//逆置
void printList();//列印連結串列
void Clear();
//void sortList();//排序
void pushBack(const Type &data);//在尾部插入一個節點
void popBack();//刪除尾節點
void pushFront(Type data);//頭插
void popFront();//刪除頭節點\
private:
Node *head;
int len;//連結串列長度
};
SList.cpp
#include <iostream>
#include <assert.h>
#include "SList.h"
using namespace std;
//節點類的建構函式
Node::Node(const Type x)
:data(x),next(NULL)
{
}
//建構函式
SList::SList()
:head(NULL),len(0)
{
}
//拷貝建構函式
SList::SList(const SList &s)
{
head = NULL;
len = s.len;
Node *current; //自己連結串列的尾部元素
Node *sCurrent = s.head;//s的第一個元素
while(sCurrent != NULL)
{
for(int i = 1; i < s.len; i++)
{
Node *newNode = new Node(NULL);
newNode->data = sCurrent->data;
newNode->next = NULL;
if(i ==1)
{
head = newNode;
current = head;
}
else
{
current->next = newNode;
current = current->next;
}
sCurrent = sCurrent->next;
}
}
}
//賦值運算子過載
SList& SList::operator=(SList &s)//賦值運算子過載()
{
if(this != &s)
{
swap(head, s.head);
}
return *this;
}
//解構函式
SList::~SList()
{
Clear();
}
//清空連結串列
void SList::Clear()
{
Node *current;
while(head != NULL)
{
current = head;
head = current->next;
delete current;
}
head = NULL;
len = 0;
}
//尾部插入新節點
void SList::pushBack(const Type &data)
{
if(head == NULL)
{
head = new Node(data);
len++;
}
else
{
Node *p = head;
while(p->next != NULL)
{
p = p->next;
}
p->next = new Node(data);
len++;
p = NULL;
}
}
//列印連結串列
void SList::printList()
{
if(head == NULL)
{
cout << "this SList is empty ! " << endl;
return ;
}
else
{
Node *temp = head;
while(temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
}
//判斷連結串列是否空
bool SList::isEmpty()
{
if(head == NULL)
return true;
else
return false;
}
//獲取連結串列長度
int SList::length()
{
return len;
}
//頭插法逆置矩陣
void SList::reverseList()
{
Node *current = head;
head = NULL;
if(current == NULL)
{
cout << "this SList is empty." << endl;
}
else
{
while(current != NULL)
{
Node *nextCurrent = current->next;
//頭插法連結串列逆置
current->next = head;//head = NULL
head = current;
current = nextCurrent;
}
}
}
//刪除尾節點
void SList::popBack()
{
if(head == NULL)
cout << "this SList is empty." << endl;
else
{
Node *p = head;
//找到倒數第二個節點
for(int i = 1; i < len-1; i++)
{
p = p->next;
}
Node *current = p->next;
p->next = current->next;
delete current;
len--;
}
}
//頭部插入
void SList::pushFront(Type Data)
{
if(head == NULL)
{
pushBack(Data);
}
else
{
Node *temp = head;
head = new Node(Data);
head->next = temp;
}
}
//頭部刪除
void SList::popFront()
{
if(head == NULL)
cout << "this SList is empty." << endl;
else
{
Node *temp = head;
head = temp->next;
delete temp;
}
}
main.cpp
#include <iostream>
#include "SList.h"
using namespace std;
int main()
{
SList myList;
myList.pushBack(1);
myList.pushBack(2);
myList.pushBack(3);
myList.printList();
myList.reverseList();
myList.printList();
myList.popBack();
myList.printList();
myList.pushFront(4);
myList.printList();
myList.popFront();
myList.printList();
return 0;
}
C++實現單鏈表(帶頭結點和尾結點) SList.h
typedef int Type;
//定義節點類
struct Node
{
Node(const Type x);
Type data;
Node *next;
};
class SList
{
public:
SList();//建構函式
SList(const SList&s);//拷貝建構函式
SList &operator=(SList &s);//賦值運算子過載
~SList();//解構函式
public:
//單鏈表的具體操作
bool isEmpty();
int length();
void reverseList();//逆置
void printList();//列印連結串列
void Clear();
//void sortList();//排序
void pushBack(const Type &data);//在尾部插入一個節點
void popBack();//刪除尾節點
void pushFront(Type data);//頭插
void popFront();//刪除頭節點\
private:
Node *head;
Node *tail;
int len;//連結串列長度
};
SList.cpp
#include <iostream>
#include <assert.h>
#include "SList.h"
using namespace std;
//節點類的建構函式
Node::Node(const Type x)
:data(x),next(NULL)
{
}
//建構函式
SList::SList()
:head(NULL),tail(NULL),len(0)
{
}
//拷貝建構函式
SList::SList(const SList &s)
{
if(s.head == NULL)
return;
Node *temp = s.head;
do{
pushBack(temp->data);
temp = temp->next;
}while(temp != s.head);
len = s.len;
}
//賦值運算子過載
SList& SList::operator=(SList &s)//賦值運算子過載()
{
if(this != &s)
{
swap(head, s.head);
swap(tail, s.tail);
}
return *this;
}
//解構函式
SList::~SList()
{
Clear();
}
//清空連結串列
void SList::Clear()
{
Node *current = head;
while(current != tail)
{
head = head->next;
delete current;
current = head;
}
head = NULL;
tail = NULL;
len = 0;
}
//尾部插入新節點
void SList::pushBack(const Type &data)
{
if(head == NULL)
{
head = new Node(data);
tail = head;
tail->next = head;
}
else
{
tail->next = new Node(data);
tail = tail->next;
tail->next = head;
}
len++;
}
//列印連結串列
void SList::printList()
{
if(head == NULL)
{
cout << "this SList is empty ! " << endl;
return ;
}
else
{
Node *temp = head;
do{
cout << temp->data << " ";
temp = temp->next;
}while(temp != head);
cout << endl;
}
}
//判斷連結串列是否空
bool SList::isEmpty()
{
if(head == NULL)
return true;
else
return false;
}
//獲取連結串列長度
int SList::length()
{
return len;
}
//頭插法逆置矩陣
void SList::reverseList()
{
if(head == NULL || head->next == tail)
{
return ;
}
tail = new Node(head->data);
Node *begin = NULL;
Node *temp = tail;
while(len--)
{
Node *del = head;
head = head->next;
delete del;
begin = new Node(head->data);
begin->next = temp;
tail->next = begin;
temp = begin;
}
head = begin;
}
//刪除尾節點
void SList::popBack()
{
if(head == NULL)
cout << "this SList is empty." << endl;
else if(head == tail)
{
delete head;
head = NULL;
tail = NULL;
}
else
{
Node *current = head;
while(current->next != tail)
{
current = current->next;
}
delete tail;
tail = current;
tail->next = head;
}
}
//頭部插入
void SList::pushFront(Type Data)
{
if(head == NULL)
{
pushBack(Data);
}
else
{
Node *temp = head;
head = new Node(Data);
head->next = temp;
tail->next = head;
}
}
//頭部刪除
void SList::popFront()
{
if(head == NULL)
{
cout << "this SList is empty." << endl;
return ;
}
else
{
Node *temp = head;
head = head->next;
tail->next = head;
delete temp;
}
}
main.cpp
#include <iostream>
#include "SList.h"
using namespace std;
int main()
{
SList myList;
myList.pushBack(1);
myList.pushBack(2);
myList.pushBack(3);
myList.printList();
myList.reverseList();
myList.printList();
myList.popBack();
myList.printList();
myList.pushFront(4);
myList.printList();
myList.popFront();
myList.printList();
return 0;
}