『壹』 鏈式棧的棧頂元素是最後輸入的元素嗎
首先,需要知道數據結構棧的特點,是先進後出或者說是後進先出。
回到你的問題上,看你怎麼理解最後輸入的元素吧。對於我的理解是,盡管棧頂元素有可能出現出棧的情況,無論是否出現出棧,出棧後的元素就不算棧中的數據,此時棧頂元素必定就是最後輸入的元素。
『貳』 鏈棧中為什麼需要頭結點
鏈棧中需要頭結點原因:因為棧是後進先出的數據結構,我們不可能直接就對棧底元素進行操作,要想操作棧底元素,必須得先依次讓非棧底元素出棧。
即使設了頭指針,也沒有用處,對棧頂元素的操作,與頭指針沒關系。所以不必設頭指針指向棧底元素。
1、頭結點不存儲數據,此時它只是個標記。鏈表從這里開始,意義在於頭結點中的next。引出後面的鏈表數據。這就是平常寫的頭結點。
2、頭結點存儲數據,它此時就不只是個標記和引出後面的鏈表數據,還有它裡面的data。意義在於data 和 next。
兩個棧共享同一存儲空間:
當程序中同時使用兩個棧時,可以將兩個棧的棧底設在向量空間的兩端,讓兩個棧各自向中間延伸。當一個棧里的元素較多,超過向量空間的一半時,只要另一個棧的元素不多,那麼前者就可以佔用後者的部分存儲空間。
只有當整個向量空間被兩個棧占滿(即兩個棧頂相遇)時,才會發生上溢。因此,兩個棧共享一個長度為m的向量空間和兩個棧分別佔用兩個長度為└m/2┘和┌m/2┐的向量空間比較,前者發生上溢的概率比後者要小得多。
『叄』 棧是不是順序存儲的線性結構啊
不一定。
棧分順序棧和鏈式棧。順序棧為棧的順序實現,順序棧為利用順序存儲結構實現的棧。
採用地址連續的存儲空間(數組)依次存儲棧中數據元素,由於人棧和出棧運算都是在棧頂進行,而棧底位置是固定不變的,可以將棧底位置設置在數組空間的起始處;棧頂位置為隨入棧和出棧操作而變化的,故需用一個整型變數top來記錄當前棧頂元素在數組中的位置。
鏈式棧為一種數據存儲結構,可以通過單鏈表的方式來實現,使用鏈式棧的優點在於它能夠克服用數組實現的順序棧空間利用率不高的特點,但是需要為每個棧元素分配額外的指針空間用來存放指針域。
(3)鏈式棧的棧底元素緩存數據嗎擴展閱讀
棧作為一種數據結構,為一種只能在一端進行插入和刪除操作的特殊線性表。它按照先進後出的原則存儲數據,先進入的數據被壓入棧底,最後的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據(最後一個數據被第一個讀出來)。棧具有記憶作用,對棧的插入與刪除操作中,不需要改變棧底指針。
在計算機系統中,棧為一個具有以上屬性的動態內存區域。程序可以將數據壓入棧中,也可以將數據從棧頂彈出。在i386機器中,棧頂由稱為esp的寄存器進行定位。壓棧的操作使得棧頂的地址減小,彈出的操作使得棧頂的地址增大。
『肆』 鏈棧的棧頂和棧底是什麼
這些都是數據結構中的知識。堆棧的特徵是先入後出,而不是隊列先入先出。堆棧的頂部是最後一個推入的元素,是鏈的末端,堆棧的底部是第一個推入的元素,是鏈的末端。
在創建線程時,堆棧是內存中的一個快速空間,用於處理函數被調用時生成的臨時變數,以及當前正在執行的函數(調用函數號)的地址。當被調用的函數在運行後返回時,程序繼續從保存在那裡的地址執行。
棧採用後進先出的數據存儲方式。底部的堆棧棧存儲變數的起始地址,和堆棧指針的地址指向當前的存儲數據,當你推到堆棧數據,根據數據類型,位元組的堆棧指針是上升的反應(如數據存儲類型,移動第四節單詞讓),堆棧指針指向四個位元組後的內存地址。
(4)鏈式棧的棧底元素緩存數據嗎擴展閱讀:
事實上,鏈堆棧也是鏈表的一種形式。頭指針總是指向表的第一個節點(或頭節點),而頂部指針總是指向堆棧的頂部。在創建鏈表時,通常有兩種插補方法:一種是頭插補方法,另一種是尾插補方法。
鏈棧是相同的,假設所創建的棧沒有頭節點,即第一個節點開始存儲數據,按照頭節點插入的方法來構建棧,頭指針是頂部指針,兩者之間沒有區別;當使用尾部插入方法構建堆棧時,頭指針不是堆棧的頂部指針。
在這種情況下,應該定義一個尾部指針,以始終指向堆棧的最後一個元素(即要推入堆棧的最後一個元素),以便尾部指針是堆棧的頂部指針。
『伍』 鏈棧和順序棧兩種存儲結構有什麼不同
存儲結構不同:
鏈棧動態分配內存存儲數據,不浪費內存,存儲的數據不連續。
順序棧使用固定大小數組保存數據,數據量小時浪費內存,過多時出問題,存儲數據連續。
它們的具體區別如下:
順序棧的實現在於使用了數組這個基本數據結構,數組中的元素在內存中的存儲位置是連續的,且編譯器要求我們在編譯期就要確定數組的大小,這樣對內存的使用效率並不高,一來無法避免因數組空間用光而引起的溢出問題。在系統將內存分配給數組後,則這些內存對於其他任務就不可用。而對於鏈棧而言,使用了鏈表來實現棧,鏈表中的元素存儲在不連續的地址,由於是動態申請內存,所以我們可以以非常小的內存空間開始,另外當某個項不使用時也可將內存返還給系統。
『陸』 解釋一下C++中鏈表和鏈棧的功能和編程思想
鏈表 是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。鏈表由一系列結點(鏈表中每一個元素稱為結點)組成,結點可以在運行時動態生成。每個結點包括兩個部分:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域。
線性表的鏈式存儲表示的特點是用一組任意的存儲單元存儲線性表的數據元素(這組存儲單元可以是連續的,也可以是不連續的)。因此,為了表示每個數據元素 與其直接後繼數據元素 之間的邏輯關系,對數據元素 來說,除了存儲其本身的信息之外,還需存儲一個指示其直接後繼的信息(即直接後繼的存儲位置)。由這兩部分信息組成一個"結點"(如下圖所示),表示線性表中一個數據元素 。
數據域 data 指針域 next
其中存儲數據元素信息的域稱作數據域(設域名為data),存儲直接後繼存儲位置的域稱為指針域(設域名為next)。指針域中存儲的信息又稱做指針或鏈。
由分別表示,,…, 的N 個結點依次相鏈構成的鏈表,稱為線性表的鏈式存儲表示,由於此類鏈表的每個結點中只包含一個指針域,故又稱單鏈表或線性鏈表.
=====================================================
三個鏈表函數(c++)
#include <stdio.h>
#include <stdlib.h>
struct Node{
int data;
Node * next;
};
void insert(Node * root,int idx,int d){
Node * tmp = root;
for(int i = 0;i<idx;i++){
tmp = tmp->next;
if(tmp == NULL) return ;
}
Node * tmp2 = new Node;
tmp2->data = d;
tmp2->next = tmp->next;
tmp->next = tmp2;
}
int del(Node * root,int idx){
Node * tmp = root;
for(int i = 0;i<idx;i++){
tmp = tmp->next;
if(tmp == NULL) return -1;
}
int ret = tmp->next->data;
tmp->next = tmp->next->next;
return ret;
}
void print(Node * root){
for(Node *tmp = root; tmp!=NULL; tmp = tmp->next)
printf("%d ",tmp->data);
printf("\n");
}
int main(){
Node * root;
root = new Node;
root->data = -1;
return 0;
}
鏈棧,可能你是說錯了,
應該是採用鏈式存儲的棧,
棧(stack)在計算機科學中是限定僅在表尾進行插入或刪除操作的線形表。
棧是一種數據結構,它按照後進先出的原則存儲數據,先進入的數據被壓入棧底,最後的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據(最後一個數據被第一個讀出來)。
棧是只能在某一端插入和刪除的特殊線性表。用桶堆積物品,先堆進來的壓在底下,隨後一件一件往堆。取走時,只能從上面一件一件取。堆和取都在頂部進行,底部一般是不動的。
棧就是一種類似桶堆積物品的數據結構,進行刪除和插入的一端稱棧頂,另一堆稱棧底。插入一般稱為進棧(PUSH),刪除則稱為退棧(POP)。 棧也稱為後進先出表(LIFO表)。
1、進棧(PUSH)演算法
①若TOP≥n時,則給出溢出信息,作出錯處理(進棧前首先檢查棧是否已滿,滿則溢出;不滿則作②);
②置TOP=TOP+1(棧指針加1,指向進棧地址);
③S(TOP)=X,結束(X為新進棧的元素);
2、退棧(POP)演算法
①若TOP≤0,則給出下溢信息,作出錯處理(退棧前先檢查是否已為空棧, 空則下溢;不空則作②);
②X=S(SOP),(退棧後的元素賦給X);
③TOP=TOP-1,結束(棧指針減1,指向棧頂)。
『柒』 棧和隊列不是邏輯結構嗎,它們的順序和鏈式才是存儲結構,一題中說棧也是存儲結構,請解釋一下
棧作為一種數據結構,是一種只能在一端進行插入和刪除操作的特殊線性表。它按照先進後出的原則存儲數據,先進入的數據被壓入棧底,最後的數據在棧頂,需要讀數據的時候從棧頂開始彈出數據。棧具有記憶作用,對棧的插入與刪除操作中,不需要改變棧底指針。
(7)鏈式棧的棧底元素緩存數據嗎擴展閱讀:
棧的順序存儲結構利用內存中的一片起始位置確定的連續存儲區域來存放棧中的所有元素,為了指示棧頂的准確位置,還需要引入一個棧頂指示變數top。設數組data[MAXSIZE]為棧的存儲空間,其中MAX-SIZE是一個預先設定的常數,為允許進棧結點的最大可能數目。
初始時棧空,top等於0。當top不等於0時,data[0]為棧底元素,即為當前停留在棧中時間最長的元素。而data[top-1]為最後入棧的元素。當top==MAXSIZE時,表示棧滿,如果此時再有結點進棧,將發生「上溢」的錯誤,而當top==0時再執行出棧操作,將發生「下溢」的錯誤。
『捌』 數據結構,鏈式棧問題,求解決。
/*===========================================
鏈棧基本操作
===========================================*/
#include<stdio.h>
#include<malloc.h>
#defineOK0
#defineERROR1
#defineSIZE20
/*===========================================
數據結構
===========================================*/
typedefstructnode
{
intdata;
structnode*next;
}NODE;
/*===========================================
創建鏈棧的第一個節點
===========================================*/
NODE*CreateStack(NODE*s,inte)
{
s=(NODE*)malloc(sizeof(NODE));
s->data=e;
s->next=NULL;
returns;
}
/*===========================================
進棧函數
===========================================*/
intPushStack(NODE*s,int*figure,inte)
{
if((*figure)>SIZE)
{
printf("棧滿,無法進棧! ");
returnERROR;
}
NODE*node,*p;
p=s;
node=(NODE*)malloc(sizeof(NODE));
node->data=e;
while(p->next!=NULL)
p=p->next;
p->next=node;//經過測試,問題就在此行
printf("測試figure:%d",*figure);
node->next=NULL;
(*figure)++;
returnOK;
}
/*===========================================
出棧函數
===========================================*/
intPopStack(NODE*s,int*figure)
{
intpopdata;
NODE*p,*q;
p=s;
if((*figure)==0)
{
printf("當前棧中無元素,操作失敗!");
returnERROR;
}
while(p->next->next!=NULL)
p=p->next;
q=p->next;
popdata=q->data;
free(q);
q=NULL;
p->next=NULL;
(*figure)--;
returnpopdata;
}
/*===========================================
顯示棧中元素
===========================================*/
voidDisplayStack(NODE*s,int*figure)
{
switch(*figure)
{
case0:
printf("當前棧中無元素!");break;
case1:
printf("當前棧中共有1個元素,是:%d",s->data);
printf(" ");
break;
default:
NODE*p=s;//一樣要給p賦值
printf("當前棧中共有%d個元素,分別是:",*figure);
do
{
printf("%d ",p->data);
p=p->next;
}
while(p!=NULL);
printf(" ");
break;
}
}
/*===========================================
銷毀鏈棧
===========================================*/
voidDestroyStack(NODE*s,int*figure)
{
NODE*p,*q;
p=q=s;
while(p->next!=NULL)
{
p=p->next;
free(q);
q=p;
}
free(p);
*figure=0;
}
/*===========================================
main函數
===========================================*/
intmain()
{
NODE*s=NULL,*h;
intcount=0;
int*figure;//指針figure為計數器,記錄鏈棧中元素個數
figure=&count;
intoption;
intdata;
printf("創建棧,輸入棧底元素:");
scanf("%d",&data);
h=CreateStack(s,data);
s=h;//這里要給s賦值
(*figure)++;
printf("鏈棧以創建完畢! ");
do
{
printf("請選擇下列操作:1.元素進棧 2.元素出棧 3.顯示棧中元素 4.銷毀鏈棧 輸入「0」退出程序 ");
printf("選擇操作:");
scanf("%d",&option);
printf(" ");
switch(option)
{
case0:
printf("操作結束,按任意鍵退出! ");break;
case1:
intpushdata;
printf("輸入進棧元素:");
scanf("%d",&pushdata);
PushStack(s,figure,pushdata);break;
case2:
intpopdata;
popdata=PopStack(h,figure);
printf("當前出棧元素是:%d",popdata);break;
case3:
DisplayStack(h,figure);break;
case4:
DestroyStack(s,figure);break;
default:
printf("無此操作! ");break;
}
}while(option!=0);
return0;
}
『玖』 分別就棧的順序存儲結構和鏈式存儲結構實現棧的各種基本操作。
順序存儲結構
#include<iostream>
typedef char ElemType;
#define MaxSize 100
using namespace std;
typedef struct
{
ElemType data[MaxSize];
int top;
}sqStack;
void InitStack(sqStack *&s);//初始化棧
void ClearStack(sqStack *&s);//摧毀棧
int StackLength(sqStack *s);//返回棧的長度
bool StackEmpty(sqStack *s);//判斷棧是否為空
int Push(sqStack *&s,ElemType e);//進棧
int Pop(sqStack *&s,ElemType &e);//出棧
int GetTop(sqStack *s,ElemType &e);//取棧頂元素
void DispStack(sqStack *s);//顯示棧中元素值
int main()
{
return 0;
}
void InitStack(sqStack *&s)//初始化棧
{
s=new sqStack;
s->top=-1;
}
void ClearStack(sqStack *&s)//摧毀棧
{
delete s;
}
int StackLength(sqStack *s)//返回棧的長度
{
return (s->top+1);
}
bool StackEmpty(sqStack *s)//判斷棧是否為空
{
return (s->top==-1);
}
int Push(sqStack *&s,ElemType e)//進棧
{
if(s->top==MaxSize-1)
return 0;
s->top++;
s->data[s->top]=e;
return 1;
}
int Pop(sqStack *&s,ElemType &e)//出棧
{
if(s->top==-1)
return 0;
e=s->data[s->top];
s->top--;
return 1;
}
int GetTop(sqStack *s,ElemType &e)//取棧頂元素
{
if(s->top==-1)
return 0;
e=s->data[s->top];
return 1;
}
void DispStack(sqStack *s)//顯示棧中元素值
{
for(int i=s->top;i>=0;i--)
cout<<s->data[i]<<" ";
cout<<endl;
}
鏈式存儲結構
typedef char ElemType;
typedef struct linknode
{
ElemType data;
struct linknode *next;
}LiStack;
void InitStack(LiStack *&s);//初始化棧
void ClearStack(LiStack *&s);//摧毀棧
int StackLength(LiStack *s);//返回棧的長度
bool StackEmpty(LiStack *s);//判斷棧是否為空
void Push(LiStack *&s,ElemType e);//進棧
int Pop(LiStack *&s,ElemType &e);//出棧
int GetTop(LiStack *s,ElemType &e);//取棧頂元素
void DispStack(LiStack *s);//顯示棧中元素值
int main()
{
return 0;
}
void InitStack(LiStack *&s)//初始化棧
{
s=new LiStack;
s->next=NULL;
}
void ClearStack(LiStack *&s)//摧毀棧
{
for(LiStack *p=s->next;p;p=p->next)
{
delete s;
s=p;
p=p->next;
}
delete s;
}
int StackLength(LiStack *s)//返回棧的長度
{
int i=0;
for(LiStack *p=s->next;p;p=p->next)
i++;
return i;
}
bool StackEmpty(LiStack *s)//判斷棧是否為空
{
return (s->next==NULL);
}
void Push(LiStack *&s,ElemType e)//進棧
{
LiStack *p=new LiStack;
p->data=e;
p->next=s->next;
s->next=p;
}
int Pop(LiStack *&s,ElemType &e)//出棧
{
LiStack *p;
if(s->next==NULL)
return 0;
p=s->next;
e=p->data;
s->next=p->next;
delete p;
return 1;
}
int GetTop(LiStack *s,ElemType &e)//取棧頂元素
{
if(s->next==NULL)
return 0;
e=s->next->data;
return 1;
}
void DispStack(LiStack *s)//顯示棧中元素值
{
LiStack *p=s->next;
for(;p;p=p->next)
cout<<p->data<<" ";
cout<<endl;
}
『拾』 帶鏈棧的棧底指針是隨棧的操作而動態變化的 這句話為什麼是對的
以上說法不夠嚴謹。
鏈式存儲的棧結構,棧底指針的動態變化是有嚴格約束條件的,即:出棧操作中棧內僅有一個元素時或者入棧操作中棧內沒有元素時,棧底指針才會變化。隨著棧操作而動態變化應該用於描述棧頂指針。
棧頂指針不變應該,但是我覺得是棧頂指針隨著棧頂元素變化而變化,棧頂指針是表示棧頂元素的位置,佔地元素不同位置,棧頂指針就不同,如同一位置不同元素的指針也是相同的,因為指針是地址,只是取這個地址的值會不同。
(10)鏈式棧的棧底元素緩存數據嗎擴展閱讀:
計算機中的堆棧主要用來保存臨時數據,局部變數和中斷/調用子程序程序的返回地址。
堆棧指針是在棧操作過程中,有一個專門的棧指針(習慣上稱它為TOP),指出棧頂元素所在的位置。
堆棧指針總是指向棧頂元素。
堆棧可以使向下生長的(向低地址),也可以是向上生長的。
如果堆棧是向上生長的,數據入棧的時候,堆棧指針先加1,再壓棧。出棧的時候先彈出數據,堆棧指針再減1。如果堆棧是向下生長的,數據入棧時指針將減1,數據出棧時指針將加1。