1. 程式人生 > >陣列和連結串列描述棧以及應用

陣列和連結串列描述棧以及應用

陣列描述棧

#pragma warning(disable:4996)
#include <iostream>
#include<iterator>
#include<algorithm>
using namespace std;

//邊長一維陣列(增加或減少)
//改變一個一維陣列的長度
template<class T>
void changeLength1D(T*& a, int oldLength, int newLength)
{
	if (newLength < 0)
	{
		cout << "錯誤:newLength 小於 0!";
		exit(-1);
	}
	T* temp = new T[newLength];
	int number = min(oldLength, newLength);
	copy(a, a + number, temp);
	delete[] a;
	a = temp;
}

template<class T>
class stack
{
public:
	virtual ~stack() {};
	virtual bool empty() const = 0;
	virtual int size() const = 0;
	virtual T& top() = 0;
	virtual void pop() = 0;
	virtual void push(const T& theElement) = 0;
};

template<class T>
class arrayStack :public stack<T>
{
public:
	arrayStack(int initialCapacity = 10);
	~arrayStack() { delete[] stack; }
	bool empty() const { return stackTop == -1; }
	int size() const { return stackTop + 1; }
	T& top()
	{
		if (stackTop == -1)
		{
			cout << "棧中沒有元素" << endl;
			exit(-1);
		}
		return stack[stackTop];
	}
	void pop()
	{
		if (stackTop == -1)
		{
			cout << "棧中沒有元素" << endl;
			exit(-1);
		}
		stack[stackTop--].~T();
	}
	void push(const T& theElement);
	void output(ostream& out) const;
private:
	friend ostream& operator<<(ostream& out, const arrayStack<T>& x);
	//當前棧頂
	int stackTop;
	//棧容量
	int arrayLength;
	//元素陣列
	T *stack;
};
template<class T>
arrayStack<T>::arrayStack(int initialCapacity)
{
	if (initialCapacity < 1)
	{
		cout << "initialCapacity must be > 0" << endl;
		exit(-1);
	}
	arrayLength = initialCapacity;
	stack = new T[arrayLength];
	stackTop = -1;
}

template<class T>
void arrayStack<T>::push(const T& theElement)
{
	//判斷是否還有空間
	if (stackTop == arrayLength - 1)
	{
		changeLength1D(stack, arrayLength, 2 * arrayLength);
		arrayLength *= 2;
	}
	stack[++stackTop] = theElement;
}

template<typename T> ostream& operator<<(ostream& out, const arrayStack<T>& x)
{
	x.output(out);
	return out;
}

template<typename T> void arrayStack<T>::output(ostream& out) const
{
	//把棧插入輸出流
	copy(stack, stack + stackTop + 1, ostream_iterator<T>(cout, " "));
}

int main()
{
	arrayStack<int> s;
	s.push(1);
	s.push(2);
	s.push(3);
	s.push(4); 
	cout << "初始棧為:";
	s.output(cout);
	cout << endl;
	cout << "棧頂元素" <<s.top() << endl;
	s.pop();
	s.output(cout);
	cout << endl;
	cout << "棧存放的元素數量"<<s.size() << endl;
	
	system("pause");
	return 0;
}

連結串列描述棧

當用連結串列描述棧時,必須要確定用連結串列的哪段作為棧頂。若用連結串列的右端作為棧頂,則棧操作top、push和pop的實現需要用時O(size())。而用連結串列的左端作為棧頂,需要呼叫的連結串列方法是get(0)、insert(0,theElement)和erase(0),其中每一個連結串列方法需要用時O(1)。所以選擇連結串列的左端作為棧頂。

#pragma warning(disable:4996)
#include <iostream>
using namespace std;

//連結串列節點的結構定義
template<class T>
struct chainNode
{
	T element;
	chainNode<T> *next;

	chainNode() {}
	chainNode(const T& element)
	{
		this->element = element;
	}
	chainNode(const T& element, chainNode<T>* next)
	{
		this->element = element;
		this->next = next;
	}
};

template<class T>
class stack
{
public:
	virtual ~stack() {};
	virtual bool empty() const = 0;
	virtual int size() const = 0;
	virtual T& top() = 0;
	virtual void pop() = 0;
	virtual void push(const T& theElement) = 0;
};

template<class T>
class linkStack :public stack<T>
{
public:
	linkStack()
	{
		stackTop = NULL;
		stackSize = 0;
	}
	~linkStack();
	bool empty() const
	{
		return stackSize == 0;
	}
	int size() const
	{
		return stackSize;
	}
	T& top()
	{
		if (stackSize == 0)
		{
			cout << "棧內無元素" << endl;
			exit(-1);
		}
		return stackTop->element;
	}
	void pop();
	void push(const T& theElement);
	void output(ostream& out) const;
private:
	friend ostream& operator<<(ostream& out, const linkStack<T>& x);
	//棧頂指標
	chainNode<T>* stackTop;
	//棧中元素個數
	int stackSize;
};

template<class T>
void linkStack<T>::pop()
{
	if (stackSize == 0)
	{
		cout << "棧內無元素" << endl;
		exit(-1);
	}
	chainNode<T>* nextNode = stackTop->next;
	delete stackTop;
	stackTop = nextNode;
	stackSize--;
}

template<class T>
void linkStack<T>::push(const T& theElement)
{
	stackTop = new chainNode<T>(theElement, stackTop);
	stackSize++;
}

template<class T>
linkStack<T>::~linkStack()
{
	while (stackTop != NULL)
	{
		chainNode<T>* nextNode = stackTop->next;
		delete stackTop;
		stackTop = nextNode;
	}
}

template<typename T> ostream& operator<<(ostream& out, const linkStack<T>& x)
{
	x.output(out);
	return out;
}

template<class T>
void linkStack<T>::output(ostream& out) const
{
	for (chainNode<T>* nextNode = stackTop; nextNode != NULL;
	nextNode = nextNode->next)
		out << nextNode->element << " ";
}

int main()
{
linkStack<int> s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
cout << "初始棧為:";
s.output(cout);
cout << endl;
cout << "棧頂元素" <<s.top() << endl;
s.pop();
s.output(cout);
cout << endl;
cout << "棧存放的元素數量"<<s.size() << endl;

system("pause");
return 0;
}

用陣列棧解決括號匹配問題

int main()
{
	arrayStack<int> s;
	string expr;
	getline(cin, expr);
	int length = (int)expr.size();
	for (int i = 0; i < length; ++i)
	{
		if (expr[i] == '(')
			s.push(i);
		else if (expr[i] == ')')
		{
			if (s.empty())
				cout << "沒有和右括號"<<i<<"匹配的左括號" << endl;
			else
			{
				cout << s.top() << ' ' << i << endl;
				s.pop();
			}
		}
	}
	while (!s.empty())
	{
		cout << "沒有和左括號"<<s.top()<<"匹配的右括號" << endl;
		s.pop();
	}
	system("pause");
	return 0;
}

相關推薦

陣列連結串列描述以及應用

陣列描述棧#pragma warning(disable:4996) #include <iostream> #include<iterator> #include<algorithm> using namespace std; //邊長

陣列連結串列佇列之間的關係及堆之間的關係

本屌最近在學習資料結構過程中,由於連續看了陣列,棧,佇列,連結串列等,一時混雜,下面摘取參考資料,供自己學習使用。 第一部分:介紹了資料儲存結構和資料結構的區別,以及連結串列和陣列的差異。 第二部分:介紹了堆和棧的區別。 (1)資料儲存結構:計算機的一個概念,描述資料在計算機中儲存方式;常用

資料結構:陣列連結串列的區別以及各自的優缺點

原文地址 http://blog.csdn.net/qq_25806863/article/details/70607204 陣列和連結串列是兩種基本的資料結構,他們在記憶體儲存上的表現不一樣,所以也有各自的特點。 大致總結一下特點和區別,拿幾個人一起去看電影時坐座位為例。 陣列的特點

陣列連結串列實現

完成一個棧總共需要完成以下操作:初始化入棧出棧檢視棧頂元素檢視棧的容量清空棧。首先是簡單的,用陣列做的,會有越界的可能。#include <stdio.h> #include <stdlib.h> typedef struct Stack {

Java 陣列連結串列的區別以及使用場景

陣列:是將元素在記憶體中連續儲存的;它的優點:因為資料是連續儲存的,記憶體地址連續,所以在查詢資料的時候效率比較高;它的缺點:在儲存之前,我們需要申請一塊連續的記憶體空間,並且在編譯的時候就必須確定好它的空間的大小。在執行的時候空間的大小是無法隨著你的需要進行增加和減少而改變的,當資料兩比較大的時候,有可能

c++分別用陣列連結串列實現的操作

棧在實際程式設計中經常會用到,本文利用陣列和連結串列分別實現了棧的操作。 1.陣列方式實現如下: #include<iostream> using namespace std; template <class T> class arraysta

陣列連結串列集合的區別應用場景以及的區別

陣列和集合的區別: 1.陣列的長度固定的,超過長度時,只能建立一個新的陣列,並把舊的陣列的值傳進去方可; 而集合的長度是動態不固定的。 2.陣列的儲存型別是單一的,同一陣列只能儲存同一資料型別的資料。 而集合可以儲存多鍾資料型別的資料。 3.陣列只能通過下標來訪

基於陣列連結串列兩種方式實現

棧是一種先進後出的資料結構,在實際程式設計棧有很廣泛的用處,Java棧已經幫我們實現好了stack類。 實現棧的兩種方式,基於陣列實現和基於連結串列實現。 1.stack介面 public interface StackADT { //入棧操作 public voi

使用陣列連結串列的方式實現

使用 陣列和連結串列 的方式實現 棧 陣列實現棧: public class Stack<Item> implements Iterable<Item> { pri

陣列連結串列分別實現類stack,隊queue

棧(stack)是一種常見資料結構,以後進先出(LIFO)著稱。比如編譯器用棧處理函式呼叫,儲存被呼叫函式的引數和區域性變數。當一個函式呼叫另一個函式時候,新的函式引數和區域性變數被入棧。呼叫結束,佔用的資源從棧釋放。 用陣列實現: class vector{ priva

連結串列建立 以及陣列建立的區別

#include<stdio.h> #include<stdlib.h> typedef struct listnode { int data; struct listnode * next; }node,*Pnode; typedef stru

陣列連結串列、佇列STL【轉】

陣列 陣列是一種最基本的資料結構,它是記憶體上的一塊連續儲存空間。正因如此陣列的隨機訪問很方便。但陣列也有其固有的限制,大小分配後不能改變。 STL中的陣列 STL中的Array是靜態陣列模板,就是我們所說的陣列。使用方法如下。     std::arra

演算法總結-陣列連結串列

1 連結串列 Dummy Node的應用 K組翻轉連結串列 http://www.lintcode.com/zh-cn/problem/reverse-nodes-in-k-group/ 連結串列劃分 http://www.lintcode.com/zh-cn/probl

資料結構之——陣列連結串列

1. 陣列 1.1 陣列為什麼從零編號? 陣列名代表陣列的首地址,陣列的下標其實代表陣列中某個元素相對首地址的偏移量,陣列的第一個元素是零偏移,因此從 0 開始。 上面其實也只是一個解釋, C 語言設計者用零開始編號,後來的各種語言也便紛紛效仿,因此就形成了這個習慣。 1

陣列連結串列的區別與優缺點

1.儲存    陣列儲存必須有提前宣告空間,因為陣列的儲存是連續的,沒有足夠的空間是無法儲存陣列的。  連結串列可以將資料儲存在不連續的空間中,從第一個空間開始,連結串列會記錄下下一個空間的位置,這樣就能檢索到整條連結串列了 2.查詢 根據陣列的特有屬性,只要找到第

一元多項式求和的兩種實現(陣列連結串列

一元多項式求和一般都是有兩種實現方式,小編下面就附上我對這兩種方式的理解和實現程式碼。 1.陣列實現。這種方式實現一元多項式加法,是把陣列下標當做一元多項式的指數,在陣列中存放係數。這種方式在實現一元多項是加法是通過遍歷陣列下標來獲取指數資訊,通過指數資訊將係數進行相加。利用陣列在實現一元多項式

C++實現陣列連結串列的排序演算法

OK,我們經常會用到排序演算法。那麼,常用的排序演算法,除了使用陣列之外,用連結串列又該如何處理呢?下面我們來做個對比: //使用插入排序對陣列進行排序 int *get_order(int *num, int length) { for(int eiter = 1; eiter <

陣列連結串列

陣列是申請的一塊連續的記憶體空間,並且在編譯階段就要確定空間大小的,同時執行階段是不允許改變的,意味著所有待辦事項在記憶體中都是相連的(緊靠在一起的)。 連結串列是動態申請的記憶體空間,現用現申,比陣列靈活。 當同時讀取所有元素時,連結串列的效率高,讀第一個,讀第二個。

陣列連結串列的區別比較

1.陣列: 陣列是將元素在記憶體中連續存放,由於每個元素佔用記憶體相同,可以通過下標迅速訪問陣列中任何元素。但是如果要在陣列中增加一個元素,需要移動大量元素,在記憶體中空出一個元素的空間,然後將要增加的元素放在其中。同樣的道理,如果想刪除一個元素,同樣需要移動大量元素去填掉被移動的元素。

陣列連結串列的例項講解——以Facebook為例

陣列支援隨機訪問,而連結串列只能順序訪問。那在實際使用中什麼樣的場合下該使用陣列,或者連結串列呢? 1、假設你要編寫一個記賬的應用程式。包含買雜貨、看電影和交會費。你每天都將記錄所有的支出,並在月底統計支出,算算當月花了多少錢。因此,你執行的插入操作很多,讀取操作很少,該使用陣列還是連