1. 程式人生 > >C++實現單鏈表的12種基本操作

C++實現單鏈表的12種基本操作

C++單鏈表的操作

2017-12-25

// 單鏈表.cpp: 定義控制檯應用程式的入口點。
//Author:kgvito 
//Date: 2017.12.25


#include "stdafx.h"
#include<iostream>
using namespace std;

typedef int DataType;
#define Node ElemType
#define ERROR NULL

//構建一個節點類
class Node						  
{
public:
	int data;     //資料域
	Node * next;  //指標域
};

//構建一個單鏈表類
class LinkList					  
{
public:
	LinkList();					  //構建一個單鏈表;
	~LinkList();                  //銷燬一個單鏈表;
	void CreateLinkList(int n);   //建立一個單鏈表
	void TravalLinkList();        //遍歷線性表
	int GetLength();              //獲取線性表長度
	bool IsEmpty();               //判斷單鏈表是否為空
	ElemType * Find(DataType data); //查詢節點
	void InsertElemAtEnd(DataType data);            //在尾部插入指定的元素
	void InsertElemAtIndex(DataType data,int n);    //在指定位置插入指定元素
	void InsertElemAtHead(DataType data);           //在頭部插入指定元素
	void DeleteElemAtEnd();       //在尾部刪除元素
	void DeleteAll();             //刪除所有資料
	void DeleteElemAtPoint(DataType data);     //刪除指定的資料
	void DeleteElemAtHead();      //在頭部刪除節點
private:
	ElemType * head;              //頭結點
};

//初始化單鏈表
LinkList::LinkList()                  
{
	head = new ElemType;            
	head->data = 0;               //將頭結點的資料域定義為0
	head->next = NULL;            //頭結點的下一個定義為NULL
}     

//銷燬單鏈表
LinkList::~LinkList()
{
	delete head;                 //刪除頭結點
} 

//建立一個單鏈表
void LinkList::CreateLinkList(int n)
{
	ElemType *pnew, *ptemp;
	ptemp = head;
	if (n < 0) {       //當輸入的值有誤時,處理異常
		cout << "輸入的節點個數有誤" << endl;
		exit(EXIT_FAILURE);
	}
	for (int i = 0; i < n;i++) {        //將值一個一個插入單鏈表中
		pnew = new ElemType;
		cout << "請輸入第" << i + 1 << "個值: " ;
		cin >> pnew->data;
		pnew->next = NULL;          //新節點的下一個地址為NULL
		ptemp->next = pnew;         //當前結點的下一個地址設為新節點
		ptemp = pnew;               //將當前結點設為新節點
	}
}

//遍歷單鏈表
void LinkList::TravalLinkList()
{
	if (head == NULL || head->next ==NULL) {
		cout << "連結串列為空表" << endl;
	}
	ElemType *p = head;                 //另指標指向頭結點
	while (p->next != NULL)        //當指標的下一個地址不為空時,迴圈輸出p的資料域
	{
		p = p->next;               //p指向p的下一個地址
		cout << p->data << " ";
	}
}

//獲取單鏈表的長度
int LinkList::GetLength()
{
	int count = 0;                  //定義count計數
	ElemType *p = head->next;           //定義p指向頭結點
	while (p != NULL)                //當指標的下一個地址不為空時,count+1
	{
		count++;                  
		p = p->next;                //p指向p的下一個地址
	}
	return count;                   //返回count的資料
}

//判斷單鏈表是否為空
bool LinkList::IsEmpty()
{
	if (head->next == NULL) {                 
		return true;
	}
	return false;
}

//查詢節點
ElemType * LinkList::Find(DataType data)
{
	ElemType * p = head;
	if (p == NULL) {                           //當為空表時,報異常
		cout << "此連結串列為空連結串列" << endl;
		return ERROR;
	}
	else
	{
		while (p->next != NULL)               //迴圈每一個節點
		{
			if (p->data == data) {
				return p;                     //返回指標域
			}
			p = p->next;
		}
		return NULL;                           //未查詢到結果
	}
}

//在尾部插入指定的元素
void LinkList::InsertElemAtEnd(DataType data)
{
	ElemType * newNode = new ElemType;    //定義一個Node結點指標newNode
	newNode->next = NULL;         //定義newNode的資料域和指標域
	newNode->data = data;
	ElemType * p = head;              //定義指標p指向頭結點
	if (head == NULL) {           //當頭結點為空時,設定newNode為頭結點
		head = newNode;
	}
	else                          //迴圈知道最後一個節點,將newNode放置在最後
	{
		while (p->next != NULL)
		{
			p = p->next;
		}
		p->next = newNode;
	}
}

//在指定位置插入指定元素
void LinkList::InsertElemAtIndex(DataType data,int n)
{
	if (n<1 || n>GetLength())                   //輸入有誤報異常
		cout << "輸入的值錯誤" << endl;
	else
	{
		ElemType * ptemp = new ElemType;        //建立一個新的節點
		ptemp->data = data;                     //定義資料域
		ElemType * p = head;                    //建立一個指標指向頭結點
		int i = 1;
		while (n > i)                           //遍歷到指定的位置
		{
			p = p->next;
			i++;
		}
		ptemp->next = p->next;                 //將新節點插入到指定位置
		p->next = ptemp;
	}
}

//在頭部插入指定元素
void LinkList::InsertElemAtHead(DataType data)
{
	ElemType * newNode = new ElemType;    //定義一個Node結點指標newNode
	newNode->data = data;
	ElemType * p = head;              //定義指標p指向頭結點
	if (head == NULL) {           //當頭結點為空時,設定newNode為頭結點
		head = newNode;
	}
	newNode->next = p->next;          //將新節點插入到指定位置
	p->next = newNode;
}

//在尾部刪除元素
void LinkList::DeleteElemAtEnd()
{
	ElemType * p = head;          //建立一個指標指向頭結點
	ElemType * ptemp = NULL;      //建立一個佔位節點
	if (p->next == NULL) {        //判斷連結串列是否為空
		cout << "單鏈表空" << endl;
	}
	else
	{
		while (p->next != NULL)   //迴圈到尾部的前一個
		{
			ptemp = p;            //將ptemp指向尾部的前一個節點
			p = p->next;          //p指向最後一個節點
		}
		delete p;                //刪除尾部節點
		p = NULL;
		ptemp->next = NULL;
	}
}

//刪除所有資料
void LinkList::DeleteAll()
{
	ElemType * p = head->next;
	ElemType * ptemp = new ElemType;
	while (p != NULL)                    //在頭結點的下一個節點逐個刪除節點
	{
		ptemp = p;
		p = p->next;
		head->next = p;
		ptemp->next = NULL;
		delete ptemp;
	}
	head->next = NULL;                 //頭結點的下一個節點指向NULL
}

//刪除指定的資料
void LinkList::DeleteElemAtPoint(DataType data)
{
	ElemType * ptemp = Find(data);    //查詢到指定資料的節點位置
	if (ptemp == head->next) {        //判斷是不是頭結點的下一個節點,如果是就從頭部刪了它
		DeleteElemAtHead();
	}
	else
	{
		ElemType * p = head;          //p指向頭結點
		while (p->next != ptemp)      //p迴圈到指定位置的前一個節點
		{
			p = p->next;
		}
		p->next = ptemp->next;         //刪除指定位置的節點
		delete ptemp;
		ptemp = NULL;               
	}

}

//在頭部刪除節點
void LinkList::DeleteElemAtHead()
{
	ElemType * p = head;
	if (p == NULL || p->next == NULL) {   //判斷是否為空表,報異常
		cout << "該連結串列為空表" << endl;
	}
	else
	{
		ElemType * ptemp = NULL;      //建立一個佔位節點
		p = p->next;
		ptemp = p->next;              //將頭結點的下下個節點指向佔位節點
		delete p;                     //刪除頭結點的下一個節點
		p = NULL;
		head->next = ptemp;           //頭結點的指標更換
	}
}

//測試函式
int main()
{
	LinkList l;
	int i;
	cout << "1.建立單鏈表   2.遍歷單鏈表   3.獲取單鏈表的長度   4.判斷單鏈表是否為空   5.獲取節點\n";
	cout << "6.在尾部插入指定元素   7.在指定位置插入指定元素   8.在頭部插入指定元素\n";
	cout<<"9.在尾部刪除元素   10.刪除所有元素   11.刪除指定元素   12.在頭部刪除元素   0.退出" << endl;
	do
	{
		cout << "請輸入要執行的操作: ";
		cin >> i;
		switch (i)
		{
		case 1:
			int n;
			cout << "請輸入單鏈表的長度: ";
			cin >> n;
			l.CreateLinkList(n);
			break;
		case 2:
			l.TravalLinkList();
			break;
		case 3:
			cout << "該單鏈表的長度為" << l.GetLength() << endl;
			break;
		case 4:
			if (l.IsEmpty() == 1)
				cout << "該單鏈表是空表" << endl;
			else
			{
				cout << "該單鏈表不是空表" << endl;
			}
			break;
		case 5:
			DataType data;
			cout << "請輸入要獲取節點的值: ";
			cin >> data;
			cout << "該節點的值為" << l.Find(data)->data << endl;
			break;
		case 6:
			DataType endData;
			cout << "請輸入要在尾部插入的值: ";
			cin >> endData;
			l.InsertElemAtEnd(endData);
			break;
		case 7:
			DataType pointData;
			int index;
			cout << "請輸入要插入的資料: ";
			cin >> pointData;
			cout << "請輸入要插入資料的位置: ";
			cin >> index;
			l.InsertElemAtIndex(pointData, index);
			break;
		case 8:
			DataType headData;
			cout << "請輸入要在頭部插入的值: ";
			cin >> headData;
			l.InsertElemAtHead(headData);
			break;
		case 9:
			l.DeleteElemAtEnd();
			break;
		case 10:
			l.DeleteAll();
			break;
		case 11:
			DataType pointDeleteData;
			cout << "請輸入要刪除的資料: ";
			cin >> pointDeleteData;
			l.DeleteElemAtPoint(pointDeleteData);
			break;
		case 12:
			l.DeleteElemAtHead();
			break;
		default:
			break;
		}
	}while (i != 0);

	system("pause");
    return 0;
}