基础知识--数组、栈、队列的静态、动态和链式实现

来源:互联网 发布:js object 获取属性 编辑:程序博客网 时间:2024/05/02 00:36

线性表

线性表的定义:线性表是n(n≥0)个元素的有限序列,当n=0,则称为空表;当n>0时,线性表通常表示为(aa,...,an),其中a1无前驱,an无后继,其余结点有且只有一个前驱和一个后继。

线性表的存储:线性表有顺序存储和链式存储两种存储结构。

线性表的操作:主要操作有初始化表、判表空、求表长、查找、插入和删除元素等。线性表的存储结构不同,具体的操作实现就不同,如表2-2所示。

2-2 线性表的两种存储结构的基本操作特点

 

顺序存储结构

链式存储结构

 

静态数组

动态数组

 

#define  ArSize  10

typedef struct {

ElemType elem[ArSize];

int  length;} SqList;

typedef struct {

 Elemtype *elem;

 int length, ArSize;

 }sqList;

typedef struct node

{ElemType  data;

 struct node*next;

}LNode;

void initList(SqList *L)

{L->length=0;}

void initList(sqList *L, int n)

{L->elem=(ElemType*)malloc(

n*sizeof(ElemType));

 L->ArSize=n;L->length=0;}

LNode *initLK( )

{LNode *head;

 head=NULL;

 return head;}

由于第i个元素ai的存储位置LOC(ai)=LOC(a1)+(i-1)×d,所以能随机查找任一个元素,时间复杂度为O(1)

只能进行顺序查找,查找一个元素平均比较次数为(n+1)/2

插入、删除时大量结点要移动,在等概率下插入、删除一个元素平均移动结点的次数分别是n/2(n-1)/2

插入、删除时只要修改相关的指针即可,时间复杂度都为O(1)


3.1 

栈的定义:栈是一种只能在表的某一端(首端)进行操作的线性数据结构。栈的操作主要有进栈和出栈,因为只能在某一端进栈出栈,所以必定是先进后出的(FILOLIFO)。

栈的存储结构:有顺序栈(静态数组或动态数组)和链栈。

栈的操作:初始化栈、进栈、出栈,通过栈顶指针(top)来操作如表2-3所示。

2-3 顺序栈和链栈的操作

 

静态数组栈

动态数组栈

链栈

类型定义

#define SSize 10

typedef struct {

ElemType elem[SSize];

int top;}SqSNode;

Typedef struct{

 ElemType *elem,*top;

 int SSize;

}DSNode;

typedef struct node

{ElemType  data;

 struct node*next;

}LSNode;

进栈

SqSNode s;

s.elem[s.top++]=e;

DSNode s;

*s.top++=e;

LSNode *top,*p;

p=new LSNode;p->data=e; p->next=top;top=p;

出栈

e=s.elem[--s.top];

e=*--s.top;

p=top;e=p->data;

top=top->next;delete(p)

栈空

s.top==0

s.top==s.elem

top==NULL

栈满

s.top==SSize

s.top==s.elem+s.SSize

空间分配失败p==NULL

栈的应用举例:表达式求值和递归的实现。

【例】算术表达式a+b*c/(d-e)-f的逆波兰式为abc*de-/+f-;

【例2】已知下列算法

void p(int n)

 { if (n>1 &&n%2==1) p(n-1);

   printf(“-”,n);

   if (n>1 &&n%2==0) p(n-1);

  }p(5)调用的结果是:4 2 1 3 5

分析:当遇到调用语句时将参数、返回地址进栈;当遇到函数结束时退栈返回。

队列

队列的定义:队列是一种只能在表的尾端进行插入操作,在首端进行删除操作的线性数据结构。它是先进先出(FIFO)的线性表。

队列的存储结构:有顺序队列循环队列,设有首指针和尾指针;链队列一般在单循环链表上实现,只设尾指针,不设首指针称循环链队列。

队列的操作:初始化队列、进队、出队,通过队列的首指针front和尾指针rear实现操作如表2-4所示。

2-4 循环队列和循环链队列的操作

 

循环队列

循环链队列

类型定义

#define QSize 10

typedef struct {

ElemType elem[QSize];

int front,rear;}SqQNode;

typedef struct node

{ElemType  data;

   struct node*next;

}LQNode;

进队

SqQNode Q;

Q.rear=(Q.rear+1)% QSize;

Q.elem[Q.rear]=e;

LQNode *rear,*p;

p=new LQNode; p->data=e; p->next=rear->next; rear->next=p; rear=p;

出队

Q.front=(Q.front+1)% QSize;

e=Q.elem[Q.front];

p=rear->next; e=p->data;(无头链表)

rear->next=p->next;delete(p)

队空

Q.front==Q.rear

rear==NULL

队满

Q.front==(Q.rear+1)%QSize

空间分配失败p==NULL

【例3-3】设循环队列Q,则当前循环队列中的元素个数是:

(Q.rear-Q.front+ QSize)%QSize.

0 0
原创粉丝点击