1. 程式人生 > >資料結構之單鏈表(C++實現)

資料結構之單鏈表(C++實現)

很早前就想用C++來實現那些常用的資料結構。

今天就算是個開端把。還是那句話,看的再多不如自己動手寫一遍。

按照自己的思路寫。首先你得熟悉那種結構的特點,然後才能談實現。

 連結串列是一種很常用的資料結構。支援在任意地方對資料進行增刪改查。

但是不支援隨機訪問。所以複雜度就有些高了。寫的時候出了個問題。

最後把記憶體查看了幾遍。並不是儲存資料的結點出問題了。而是在連結串列轉置

的時候用到的那個int *p = new int(length).出問題了。因為習慣了C的malloc,

所以就那麼寫。最後才發現這樣並沒有申請到需要的lenght個int長度的記憶體。

把()改成[]就好了。所以只有多用才能發現更多的錯誤。否則永遠停留在理論層面上,

沒有實踐,貌似就是扯淡。

Link的功能不多,就那麼些。當然你可以擴充套件。

gcc和vc6.0下通過。一個.cpp檔案對應一個.h檔案這樣的規範比較好。

.h裡面的函式如果很小就可以寫出來,如果比較大,就寫在.cpp檔案裡面。

以後會陸陸續續實現那些常用的資料結構C++版本。

你們的訪問和評論是俺前進的強大動力啊。所以,親啊,試試多花幾秒鐘在鍵盤上寫寫你的對問題

的看法。大笑

轉載請註明出處,謝謝!

 Link.h

#ifndef LINK_H
#define LINK_H
//結構體的定義
struct myLink{
	int value;	//資料域
	struct myLink *next;	//指標域
};
class Link{
private:
	struct myLink *head;	//頭指標
	struct myLink *cur;	//當前位置的指標
	int length;	//link的長度
public:
	Link(){//default constructor
		head = cur =NULL;	//預設link是空的
		length = 0;
	}
	Link(const Link &L){//禁止copy constructor
		throw "not allowed";
	}
	Link& operator=(const Link &L){//禁止assignment constructor
		throw "not allowed";
	}
	void add(int data);//新增元素到連結串列,預設到尾部新增
	int getData(int pos);//得到第pos位置的元素
	int remove(int pos);//移除某個位置的元素
	void sort();//對link進行排序
	int insert(int pos, int data);//在第pos個位置data插入到link
	void reverse();//對link進行轉置
	void display();//對link的元素進行顯示
	int modify(int pos, int data);//更改第pos個位置的data
	int getLength(){//得到link的長度
		return length;
	}
	~Link();	//destructor
};
#endif	

Link.cpp

#include <iostream>
#include "Link.h"

void Link::add(int data){
	struct myLink *u = new struct myLink;
	u->value = data;
	u->next = NULL;
	if (NULL == head){//頭結點也儲存資料
		head = u;
		cur = u;
	}else {
		cur->next = u;
		cur = u;	//當前指標改為u
	}
	length++;
}
int Link::getData(int pos){
	if (length >= pos && length > 0){//連結串列非空並且無越界
		int count = 0;//計數
			while (pos != count){
				count++;
				if (1 == count)
					cur = head;//頭指標成為當前指標
				else
					cur = cur->next;//指標後移
			}
		return cur->value; 
	}
	return -1;	//其它返回-1
}
int Link::remove(int pos){
	if (length >= pos && length > 0){//連結串列非空並且無越界
		int count = 1;//計數
		while (pos != count){//得到第pos位置的前一個指標
			count++;
			if (2 == count)
				cur = head;//頭指標成為當前指標
			else
				cur = cur->next;//指標後移
		}
		struct myLink *temp;
		if (1 == count){
			//如果remove第一個資料,就應該特殊處理下,因為頭結點也儲存了data
			temp = head; 
			head = temp->next;
			delete temp;
		}else {
			temp = cur->next;
			cur->next = temp->next;
			delete temp;
		}
		length--;	//不要忘了將length--
		return 0;
	}
	return -1;//其它返回-1
}
int Link::insert(int pos, int data){
	if (length >= pos && length > 0){//連結串列非空並且無越界
		int count = 1;//計數
		while (pos != count){//找到當前位置的前一個指標
			count++;
			if (2 == count)
				cur = head;//頭指標成為當前指標
			else
				cur = cur->next;//指標後移
		}
		struct myLink *u = new struct myLink;
		u->value = data;
		if (1 == count){
			u->next = head;
			head = u;//當前結點成為頭結點
		}else {
			u->next = cur->next;//新加結點的指向當前結點的下一個結點
			cur->next = u;	//當前結點指向新加結點
		}
		length++;	//不要忘了
		return 0; 
	}
	return -1;//其它返回-1
}
void Link::sort(){
	if (length > 1){
		int count = 0;
		while (length - 1 != count){
			int i = count + 1;
			struct myLink *temp = head;
			cur = head;	//當前結點指向頭結點
			while (length != i ){
				if (cur->value > cur->next->value){
					cur->value += cur->next->value;
					cur->next->value = cur->value - cur->next->value;
					cur->value -= cur->next->value;
				}
				cur = cur->next; 
				i++;
			}
			temp = temp->next;
			count++;
		}
	}
}
void Link::reverse(){//通過改變指標域來轉置,效率更高點
	if (length > 0){
		int count = 0;
		int *p = new int[length];//不要寫成new int(length),最後俺找了2個多小時才找出來這裡出錯了
		//new int(length)沒有申請length個int的記憶體,
		cur = head;	//當前結點指向頭結點
		while (length != count){
			p[count] = (int)cur;//將指標儲存在p[i]中
			count++;
			cur = cur->next;
		}
		count = 0;
		struct myLink *temp = head;	//輔助指標
		while (length != count){
			count++;
			cur = (struct myLink *)p[length - count];//反轉
			if (1 == count){
				head = cur;//最後一個結點成為頭結點
				temp = head;
			}
			else {
				temp->next = cur;	//當前結點成為上一個結點的後繼結點
				temp = temp->next;	//temp後移
			}
		}
		cur->next = NULL;
		delete []p;
	}
}
int Link::modify(int pos, int data){
	if (length >= pos && length > 0){//連結串列非空並且無越界
		int count = 0;//計數
		while (pos != count){
			count++;
			if (1 == count)
				cur = head;//頭指標成為當前指標
			else
				cur = cur->next;//指標後移
			}
		cur->value = data;
		return 0; 
	}
	return -1;//其它返回-1
}
void Link::display(){
	if (length > 0){
		std::cout<<"data in the Link is:"<<std::endl;
		int count = 0;
		cur = head;	//當前結點指向頭結點
		while (length != count){
			count++;
			std::cout<<"the "<<count<<" data is "<<cur->value<<std::endl;
			cur = cur->next;
		}
	}
}
Link::~Link(){
	if (NULL != head){
		cur = head;	//從頭結點開始delete
		while (0 != length){
			head = cur->next;	//頭結點後移
			delete cur;
			cur = head;
			length--;
		}
	}
}