【代碼】單鏈表操作——增刪改查、反序輸出、反轉鏈表

聲明
linklist.h

#pragma once
#include<iostream>
using namespace std;

//鏈表節點信息
struct Info {
	int data;
	Info *next;

	Info ():data(NULL),next(NULL){
	}
	Info(int num):data(num),next(NULL){}
};
typedef struct Info * Link;


void CreatLink(int, Link);   //創建鏈表,帶頭結點
int IsNull(Link);    //判斷鏈表是否爲空
void Insert(Link, Info *, int);   //再p結點後插入數據
Link RevervalLink(Link);   //反轉鏈表
void Delete1(int, Link);    //刪除某個位置結點
void Delete2(int, Link);    //刪除某個數據
void SelectInfo(Link, int);  //查找某結點所在位置
void UpdataInfo(Link, int, int);  //修改某位置數據
void Sort(Link);     //升序排序
int Length(Link);   //求鏈表長度
Link BeforInfo(Link, Info *);   //求某結點的前驅結點
void Display(Link);      //順序輸出鏈表 
void Display2(Link);    //逆序輸出鏈表

linklist.cpp

#include"linklist.h"

//創建鏈表 或插入鏈表尾部
void CreatLink(int num, Link head)
{
	Link plist = head;
	while (plist->next != NULL) { plist = plist->next; }
	Info * next1 = new Info(num);
	plist->next = next1;
}

//插入鏈表,在p結點後插入數據
void Insert(Link head, Info*  pinfo,int data)
{
	Link plist = head->next;
	while (plist != NULL)   
	{
		if (plist == pinfo)     
		{
			Info * tinfo = new Info(data);
			tinfo->next = pinfo->next;
			pinfo->next = tinfo;
			break;
		}
		plist = plist->next;
	}
}


//反轉鏈表
//需要三個結點--前驅結點,當前結點,後續結點
Link RevervalLink(Link head)
{
	Info * tinfo , *binfo = head->next;
	Link plist = binfo->next;
	if (IsNull(head)) return NULL;
	binfo->next = NULL;     //第一個結點反轉後會變爲最後一個結點
	while (plist != NULL){
		tinfo = plist->next;
		plist ->next= binfo;
		binfo = plist;
		plist = tinfo;
	} 
	//plist爲空跳出循環,此時反轉的最後一個結點爲binfo
	head->next = binfo;     
	return head;
}


//判斷鏈表是否爲空,爲空返回1
//因爲帶了頭結點,頭結點不爲空
int IsNull(Link head)
{
	return (head->next == NULL);
}


//輸出
void Display(Link head)
{
	Info * plist = head->next;
	while (plist != NULL) {
		cout << plist->data << " ";
		plist = plist->next;
	}
	cout << endl;
}

//逆序輸出鏈表
//遞歸
void Display2(Link head)
{
	Info * plist = head;
	if (plist == NULL) return;
	Display2(plist->next);
	cout << plist->data << "  ";
}

//前驅節點
Link BeforInfo(Link head, Info * pInfo)
{
	Link plist = head;
	if (plist->next == NULL) return NULL;
	while (plist->next != NULL)
	{
		if (plist->next == pInfo)
			return plist;
		plist = plist->next;
	}
}

//刪除節點(第幾個),不算頭結點
/*這裏以尋找前驅節點的方式*/
void Delete1(int i, Link head)
{
	Link plist = head->next;
	if (IsNull(head))	return; 
	if (i == 1) { head->next = plist->next; delete plist; }
	if (Length(head) < i) { cout << "刪除位置超過鏈表長度"; return; }
	int k = 1;
	while (plist != NULL && k <= i) {
		if (k++ == i) {
			Link tlist = BeforInfo(head, plist);
			tlist->next = plist->next;
			delete plist;
			break;
		}
		plist = plist->next;
	}
}


//刪除指定值的節點
/*這裏以交換數據的方式*/
void Delete2(int data, Link head)
{
	bool flag = false;
	if (IsNull(head)) return;
	Link plist = head->next;
	while (plist != NULL)
	{
		if (plist->data == data)
		{
			Link tlist = plist->next;
			plist->next = plist->next->next;
			plist->data = tlist->data;
			delete tlist;
			//break;           //只刪除第一個出現的節點就在此加上break;
			flag = true;
		}
		plist = plist->next;
	}
	if (!flag) cout << "無查找數據" << endl;
}

//求單鏈表的長度 加上頭結點
int Length(Link head)
{
	Link plist = head;
	int Len = 0;
	while (plist != NULL)
	{
		Len += 1;
		plist = plist->next;
	}
	return Len;
}

//排序鏈表
/*冒泡排序*/
void Sort(Link head)
{
	if (IsNull(head)) return;
	Link plist;
	int tdata;     //中間變量,節點數據信息
	int Len = Length(head);
	for (int i = 1; i < Len - 1; i++)
	{
		plist = head->next;
		while (plist != NULL && plist->next != NULL)
		{
			if (plist->data > plist->next->data)
			{
				tdata = plist->data;
				plist->data = plist->next->data;
				plist->next->data = tdata;
			}
			plist = plist->next;
		}
	}
}


//求某元素所在位置(全部位置)
void SelectInfo(Link head, int data)
{
	Info * plist = head->next;
	int i = 0;
	bool flag = false;
	cout << data << "在鏈表中的位置爲:";
	while (plist != NULL)
	{
		i += 1;
		if (plist->data == data)
		{
			cout << " " << i << "  ";
			flag = true;
		}
		plist = plist->next;
	}
	if (!flag) cout << "無查找數據" << endl;
}

//修改某位置結點數據爲num
void UpdataInfo(Link head, int site, int data)
{
	if (site >= Length(head)) 
	{
		cout << "欲修改位置超出鏈表長度" << endl;
		return;
	}
	Link plist = head->next;
	int flag = 1;
	while (plist != NULL)
	{
		if (flag == site) {
			plist->data = data;
			return;
		}
		flag += 1;
		plist = plist->next;
	}
}

這是我做測試寫的主函數,有需求自行修改。
源.cpp

#include"linklist.h"

/*帶頭結點的鏈表操作*/
int main()
{
	Link headlist = new Info;    //創建頭結點 ,頭結點不存儲數據
	int num[] = {40,3,9,5,6,70,5,6,8,6,23 };
	for (int i = 0; i < (sizeof(num) / sizeof(num[0])); i++)
		CreatLink(num[i], headlist);
	Display(headlist);
//	Delete1(3,headlist);
//	Delete2(6, headlist);
	Sort(headlist);
	Display(headlist);
	Link plist = RevervalLink(headlist);
	Display(plist);
	SelectInfo(plist, 6);
	cout << endl;
	UpdataInfo(plist, 2, 50);
	Display(plist);
	system("pause");
	return 0;
}

代碼記錄一下,僅供參考,鐵憨憨不要直接複製,有問題歡迎討論。
編譯器:VS 2017
不能保證到其他編譯器下能成功運行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章