1. 程式人生 > >C++單鏈表的建立(有頭節點)

C++單鏈表的建立(有頭節點)

#ifndef chainWithHeader_
#define chainWithHeader_
#include<iostream>
#include<string>    //陣列
#include<algorithm> //STL中的演算法
#include<sstream>  //istringstream流
#include<exception>//異常處理
#include<vector>//迭代器
#include<numeric>//標準庫中的數學操作函式
#include<iterator>
#include<array>
#include "chainNode.h"
using namespace std;
template<typename T>
class chainWithHeader
{
public:
	 chainWithHeader(int initialCapacity=10);
	~chainWithHeader();



	bool empty() const { return listSize == 0; }
	int size() const { return listSize; }
	void insert(int theIndex, const T& theElement);
	void insertsort();
	void output(ostream& out)const;
	void bubblingSort();
	void selectionSort();
	void rankSort();
private:
	chainNode<T>*headerNode;   //指向連結串列第一個節點的指標
	int listSize;
};
template<typename T>
chainWithHeader<T>::chainWithHeader(int initialCapacity)
{
	if (initialCapacity<1)
	{
		ostringstream s;
		s << "Initial capacity= " << initialCapacity << "Must be>0";
		throw illegalParameterValue(s.str());
	}
	headerNode = new chainNode<T>();
	headerNode->next= NULL;
	listSize = 0;
}
//解構函式,~chain(),思想,不斷的刪除首節點
template<typename T>
chainWithHeader<T>::~chainWithHeader()
{
	while (headerNode->next!= NULL)
	{
		chainNode<T>* nextNode = headerNode->next;
		delete headerNode;
		headerNode = nextNode;
	}
}
//插入函式
template<typename T>
void chainWithHeader<T>::insert(int theIndex, const T& theElement)
{
	if (theIndex == 0)//把連結串列頭賦給自己
		headerNode->next = new chainNode<T>(theElement, headerNode->next);
	else
	{
		chainNode<T>* p =headerNode->next;
		for (int i = 0; i < theIndex - 1; i++)
			p = p->next;
		p->next = new chainNode<T>(theElement, p->next);
	}
	listSize++;
}
//輸出函式
template<typename T>
void chainWithHeader<T>::output(ostream& out)const
{
	for (chainNode<T>*p = headerNode; p->next != NULL; p = p->next)
		out << p->next->element << " ";
}
//插入排序
template<typename T>
void chainWithHeader<T>::insertsort()
{
	//將連結串列分成兩段,一段有1個元素,另一段有n-1個元素,這是基礎
	chainNode<T>*p= headerNode->next->next;     //p代表第二個節點,此表從第二個節點開始
	headerNode->next->next = NULL;              //只要一個元素的表,等待插入          
	chainNode<T>*r,*q;
	while (p!= NULL)
	{
		r = p->next;                           //儲存p後面還沒比較的節點
		q = headerNode;                        //新表的表頭,每次從表頭開始找
		while (q->next != NULL&&q->next->element<= p->element)  //找到大於p的那個節點前驅
			q = q->next;
		p->next = q->next;                                 //p->next指向q->next的值
		q->next = p;               //q->next指向p處的值,相當於從p指的連結串列找到一個元素放入headerNode所指連結串列的合適位置
		p = r;                                             //進行下一次比較
	}
}
//氣泡排序(有頭結點)
template<typename T>
void chainWithHeader<T>::bubblingSort()
{
	    chainNode<T>*pr, *pt,*pb,*pf,*pd;//pd表示每次要比較的尾元素,pr表示比較元素的前一個,pt表示比較元素的後一個
	    pb = headerNode;            //pb為第一個比較元素的前驅
	    pr = headerNode->next;
	    pd = NULL;
		pf = headerNode;            //pf就是為了得到每次排完序的頭節點
		bool swapped = true;        //為了在已經有序的情況下能及時退出
		while (pf->next!=pd&&swapped)
		{
			pb = pf;                //pb為第一個比較元素的前驅
			pr = pf->next;
			swapped = false;        //目前為止未交換
			while (pr->next!=pd)
			{
                pt = pr->next;
				if (pr->element > pt->element)//如果兩相鄰的節點無序,則交換
				{
					pb->next = pt;
					pr->next = pt->next;
					pt->next = pr;
					swapped = true;
				}
				pb = pb->next;
				pr = pb->next;
			}
			pd = pr;//新的末尾
		}
}
//選擇排序(有頭節點)
template<typename T>
void chainWithHeader<T>::selectionSort()
{
	chainNode<T>*pd,*pf,*pe,*pa,*pmax;
	pf = headerNode;
	pd = NULL;
	bool sorted = false;                         //已經排好序之後退出迴圈
	while (pf->next->next!=pd&&!sorted)
	{
		pmax = pf;
		pa= pf->next;
		sorted = true;
		T temp;
		while (pa->next!= pd)
		{
			if (pmax->next->element<=pa->next->element)//找最大的元素
				pmax= pa;
			else sorted = false;
	        pe = pa;                           //記錄每次查詢完的最後一個元素的前驅
			pa= pa->next;
		}
		/*pb = pe->next;
		pbmax = pmax->next;

		pmax->next = pb;
		pbmax->next = pb->next;
		pb->next = pbmax->next;
		pe->next = pbmax;*/
		temp = pmax->next->element;          //和最大值和尾值交換
		pmax->next->element=pe->next->element;
		pe->next->element = temp;
        
		pd = pe->next;                             //記錄尾節點,值最大
	}
}
//計數排序
template<typename T>
void chainWithHeader<T>::rankSort()
{
	//求排名
	chainNode<T>*p, *pr;
	p = headerNode->next->next;       //指向第二個元素
	int*r= new int[listSize]();   //記錄排名,預設初始化為0
	int i = 1,j=0;
	while (p != NULL)
	{
		pr = headerNode->next;
		j = 0;
		while (pr!= p)
		{
            if(pr->element <= p->element)
				 ++r[i];
			else ++r[j];
			pr = pr->next;
			++j;
		}
		p = p->next;
		++i;
	}
	//根據名次排列
	chainNode<T>*pb = headerNode->next;
	int k = 0,t;
	T temp;
	while (pb != NULL)
	{
		 int i =0;
		chainNode<T>*pd = headerNode->next;
		while (k!=r[i])
		{
			pd = pd->next;
			++i;
		}
		if (k!=r[k])         //如果實際位置和名次相同,則不交換
		{
			//交換資料
			temp = pb->element;
			pb->element = pd->element;
			pd->element = temp;
            //交換名次
			t = r[i];
			r[i] = r[k];
			r[k] = t;
		}
		pb = pb->next;
		++k;
	}
	delete [] r;
}

#endif


相關推薦

C++單鏈建立節點

#ifndef chainWithHeader_ #define chainWithHeader_ #include<iostream> #include<string> //陣列 #include<algorithm> //STL

連結串列的建立插法和尾插法無頭節點

結構宣告 typedef int ElementType; typedef struct Node { ElementType data; struct Node *Next;

C++ 單鏈建立、插入和刪除

#include <iostream> #include <stdio.h> #include <string> #include <conio.h> /** * cstdio是將stdio.h的內容用C++標頭檔案的形式表

單鏈1悲劇文本

over delete stream oid type cout null out PE #include"iostream" using namespace std; typedef char element; class List{ private: elem

6-1 單鏈逆轉20 point(s)

本題要求實現一個函式,將給定的單鏈表逆轉。 函式介面定義: List Reverse( List L ); 其中List結構定義如下: typedef struct Node *PtrToNode; struct Node { ElementType Data; /* 儲存結點資料 */

單鏈反轉帶頭結點版

#ifndef REVERSE_LIST_H_INCLUDED #define REVERSE_LIST_H_INCLUDED LinkList reverse_list(LinkList head) { LinkList p1=head;//p1指向頭結

C++寫的帶有結點單鏈建立,插入,刪除,顯示

#include<iostream> usingnamespacestd; structlink { chardata; structlink*next; }; link*head,*tail;//建立頭指標和尾指標 intcreat(); /******

C 】在單鏈中插入一個新節點的嘗試

根據《C和指標》中講解連結串列的知識,記錄最終寫一個在單鏈表中插入一個新節點的函式的過程,這個分析過程十分的有趣,準備了兩篇博文,用於記錄這個過程。 連結串列是以結構體和指標為基礎的,所以結構體和指標是需要首先掌握的知識,掌握之後,最後要明白這個問題:結構體的自引用 這時

帶頭結點的單鏈操作插法-c++

span str out let 單鏈表 null 頭結點 操作 truct c++編寫 帶頭結點的單鏈表操作(頭插法)(和c語言差不多) #include<iostream> #include<conio.h> using namespa

節點的刪除data升序重復

color ant 升序 del 大於 fin printf 逆向 一個 #include<stdio.h>#include<stdlib.h>#define N 9typedef struct node{ int data; struct

判斷單鏈中是否循環鏈

創建 代碼實現 分享圖片 post 圖片 sca struct init 技術 有環的定義:鏈表的尾結點指向了鏈表中的某個結點,如下圖所示 判斷是否有環,兩種方法: 方法1:使用p、q兩個指針,p總是向前走,但q每次都從頭開始走,對於每個節點看p走的步數和q是否一樣,如上

C語言面向物件程式設計:單鏈實現5

 前面我們介紹瞭如何在 C 語言中引入面嚮物件語言的一些特性來進行面向物件程式設計,從本篇開始,我們使用前面提到的技巧,陸續實現幾個例子,最後呢,會提供一個基本的 http server 實現(使用 libevent )。在這篇文章裡,我們實現一個通用的資料結構:單鏈表。  

C#-XML檔案提取字串+字串存為XML檔案+建立XML自定義節點檔案+讀取節點內容

一、將字串寫入xml檔案(並儲存) 寫入:  XmlDocument xdoc = new XmlDocument();  xdoc.LoadXml(“xmlstring”); 儲存:  xdoc.Save(“pathsave.xml”) 二、將

關於連結串列的面試問題判斷一個單鏈中是否

判斷一個單鏈表中是否有環  首先連結串列結點宣告如下: struct ListNode { int key; ListNode * next; }; 思路:如果一個單鏈表中有環,用一個指標去遍歷,永遠不會結束,所以可以用兩個指標,一個指標一次走一步,另

返回單鏈中第k個節點leet簡單篇八百七十六題

給定一個帶有頭結點 head 的非空單鏈表,返回連結串列的中間結點。 如果有兩個中間結點,則返回第二個中間結點。 示例 1: 輸入:[1,2,3,4,5] 輸出:此列表中的結點 3 (序列化形式:[3,4,5]) 返回的結點值為 3 。 (測評系統對該結點序列化表述

資料結構及演算法——單鏈逆轉C語言不間斷更新

題目來源:浙大程式設計類實驗輔助教學平臺 本題要求實現一個函式,將給定的單鏈表逆轉。 函式介面定義: List Reverse( List L ); 其中List結構定義如下: typedef struct Node *PtrToNode; stru

c++實現 c++單鏈的實現採用模板類

函式實現資料的插入(頭插&&尾插)、刪除(頭刪&&尾刪)、查詢、按值插入、按值刪除、求長、單鏈表清除、單鏈表摧毀、資料的逆置以及資料排序 main函式 #include"List.h"//單鏈表 void main() { List&l

資料結構學習(二)——單鏈的操作之插法和尾插法建立連結串列

連結串列也是線性表的一種,與順序表不同的是,它在記憶體中不是連續存放的。在C語言中,連結串列是通過指標相關實現的。而單鏈表是連結串列的其中一種,關於單鏈表就是其節點中有資料域和只有一個指向下個節點的指標域。建立單鏈表的方法有兩種,分別是頭插法和尾插法。 所謂頭插法,就是按節

C++ 單鏈表基本操作分析與實現 連結串列   連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點連結串列中每一個元素稱為結點組成,結

連結串列   連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:一個是儲存資料元素的資料域,另一個是儲存下一個結點地址的指標域。 相比於線性表

單鏈建立插法與尾插法

1、採用頭插入法建立單鏈表的思路:首先建立一個空表,生成一個新的節點;並將讀取到的資料放入新節點的資料域中,然後將該節點插入到當前連結串列的表頭,即就是頭結點之後;直到插入元素完成。 2、效果:採用頭