基本数据结构——栈、队列和单链表
2012-12-03 14:32
295 查看
按照《IA》的说法,基本数据结构还包括有根树,但我这里想把这三个单独拿出来总结,有根树放在二叉查找树、红黑树和字典树这样的实例中总结。
栈、队列和单链表,都属于线性表的内容,都具有线性结构的特点,其形式化的表述为:
1、存在唯一的一个被称为“第一个”的数据元素;
2、存在唯一的一个被称为“最后一个”的数据元素;
3、除第一个之外,集合中的每个数据元素均只有一个前驱;
4、除最后一个外,集合中的每一个元素都只有一个后继。
简单的理解,可以认为,所谓线性表,是指从第一个到最后一个元素,有且仅有一条遍历所有数据元素的路线。
栈和队列都是一种特殊的线性表,栈是入栈(Insert)和出栈(pop)操作均针对栈顶元素的线性表,即通常所说的后进先出(LIFO),而队列则是进队在队尾,出队在队头的线性表,通常称之为先进先出“FIFO”。
栈在计算机中最大的应用就是函数调用时断点信息的保存以及局部变量的存储。
栈还有一些其他的应用,如整除倒取余的数制转换、括号匹配、穷举法迷宫求解、表达式求值等等,尤其是在函数的递归调用中,比如求解斐波那契数列,栈的存在大大简化了代码的编写,当然由于重复计算,此时算法的时间效率并不理想,不适合规模过大的问题,是不是可以应用查表的方式改善?
队列的主要应用则在于多线程间信息的存储和读取。
栈和队列可以用顺序结构实现,比如数组:
可以用数组S
来实现一个至多有n个元素的栈,该数组有个属性top(S),来指向最近插入的元素。
有关栈的三种基本操作:
Stack_Empty(S)
if(top(S)==0)
return TRUE
else return FALSE
PUSH(S,x)
top(S)=top(S)+1
S[top(S)]=x
POP(S)
if Stack_Empty(S)
error "underflow"
else
top(S)=top(S)-1
return S[top(S)+1]
进队和出队的操作类似,需要注意的是进队和出队都要检测溢出。
线性表还可以用非连续的的方式存储,即线性链表或单链表,在单链表的一个节点中,包含两个域:数据域和指针域,即data和next
单链表原理简单,但基于单链表的问题往往非常巧妙,基本操作如单链表的建立、测长、遍历、插入、删除、排序、逆置势必需要掌握的,其他像如何判断单链表是否有环,环的入口和长度,两个单链表是否相交(如相交则求相交的第一个元素)等等也需要熟悉,后面这些单独总结吧,附几个基本操作的C++代码:
栈、队列和单链表,都属于线性表的内容,都具有线性结构的特点,其形式化的表述为:
1、存在唯一的一个被称为“第一个”的数据元素;
2、存在唯一的一个被称为“最后一个”的数据元素;
3、除第一个之外,集合中的每个数据元素均只有一个前驱;
4、除最后一个外,集合中的每一个元素都只有一个后继。
简单的理解,可以认为,所谓线性表,是指从第一个到最后一个元素,有且仅有一条遍历所有数据元素的路线。
栈和队列都是一种特殊的线性表,栈是入栈(Insert)和出栈(pop)操作均针对栈顶元素的线性表,即通常所说的后进先出(LIFO),而队列则是进队在队尾,出队在队头的线性表,通常称之为先进先出“FIFO”。
栈在计算机中最大的应用就是函数调用时断点信息的保存以及局部变量的存储。
栈还有一些其他的应用,如整除倒取余的数制转换、括号匹配、穷举法迷宫求解、表达式求值等等,尤其是在函数的递归调用中,比如求解斐波那契数列,栈的存在大大简化了代码的编写,当然由于重复计算,此时算法的时间效率并不理想,不适合规模过大的问题,是不是可以应用查表的方式改善?
队列的主要应用则在于多线程间信息的存储和读取。
栈和队列可以用顺序结构实现,比如数组:
可以用数组S
来实现一个至多有n个元素的栈,该数组有个属性top(S),来指向最近插入的元素。
有关栈的三种基本操作:
Stack_Empty(S)
if(top(S)==0)
return TRUE
else return FALSE
PUSH(S,x)
top(S)=top(S)+1
S[top(S)]=x
POP(S)
if Stack_Empty(S)
error "underflow"
else
top(S)=top(S)-1
return S[top(S)+1]
进队和出队的操作类似,需要注意的是进队和出队都要检测溢出。
线性表还可以用非连续的的方式存储,即线性链表或单链表,在单链表的一个节点中,包含两个域:数据域和指针域,即data和next
单链表原理简单,但基于单链表的问题往往非常巧妙,基本操作如单链表的建立、测长、遍历、插入、删除、排序、逆置势必需要掌握的,其他像如何判断单链表是否有环,环的入口和长度,两个单链表是否相交(如相交则求相交的第一个元素)等等也需要熟悉,后面这些单独总结吧,附几个基本操作的C++代码:
#include <iostream> using namespace std; typedef struct student { int data; student *next; }node; //创建链表 node *Create() { node *head,*pNow,*temp; int data,cycle=1; head=new node; pNow=head; while(cycle) { cout<<"please enter a num"<<endl; cin>>data; if(data!=0) { temp=new node; temp->data=data; pNow->next=temp; pNow=temp; } else cycle=0; } pNow->next=NULL; head=head->next; cout<<head->data<<endl; return head; } //使用遍历的方法测量链表长度 int GetLength(node *head) { int length=0; node *pNow; pNow=head; while(pNow!=NULL) { length++; pNow=pNow->next; } return length; } //遍历 void Print(node *head) { node *pNow=head; while(pNow!=NULL) { cout<<pNow->data<<endl; pNow=pNow->next; } } //删除链表中的某个值,插入的考量类似,链表的排序可以采用选择排序的策略 node *delElement(node *head,int data) { node *pNow=head; node *pre=pNow; while(pNow->data!=data&&pNow->next!=NULL) { pre=pNow; pNow=pNow->next; } if(pNow->data==data) { if(pNow==head) { head=pNow->next; delete pNow; } else { pre->next=pNow->next; delete pNow; } } else { cout<<"Couldnt find num"<<data<<endl; } return head; } //链表的逆置,需要一个临时变量保存pre节点 node *Reve(node *head) { node *pre,*pNow,*temp; if(head==NULL||head->next==NULL) return head; pre=head; pNow=head->next; pre->next=NULL; while(pNow->next!=NULL) { temp=pNow->next; pNow->next=pre; pre=pNow; pNow=temp; } pNow->next=pre; head=pNow; return head; }
相关文章推荐
- 基本数据结构(栈和队列)
- 数据结构基础(8) --单链表的设计与实现(1)之基本操作
- 【C++数据结构】几种单链表的模类板实现及基本操作
- 栈和队列数据结构的基本概念及其相关的Python实现
- 算法导论第十章 基本数据结构实现(栈,队列,链表),课后题答案
- 基本数据结构-队列的实现及其运用
- 数据结构 队列的基本操作
- 基本数据结构——栈、队列和链表
- 基本数据结构:队列(queue)
- Python实现基本数据结构---队列操作
- PTA数据结构之 单链表的基本运算
- 【数据结构与算法】基本数据结构——队列的顺序表示
- 基本数据结构-队列的实现及其运用
- 数据结构 循环队列的基本操作
- 第九篇:基本数据结构——队列的链式表示
- 基本数据结构:链式队列
- 算法与数据结构-队列的基本操作C语言实现
- 数据结构循环队列的基本操作(C语言)
- 栈与队列_第10章_基本数据结构_算法导论
- 基本数据结构:队列(一:数组实现)