您的位置:首页 > 理论基础 > 数据结构算法

算法导论_第十章_基本数据结构

2016-06-30 15:33 656 查看

算法导论_第十章_基本数据结构
队列和栈:

队列为先进先出,栈为先进后出。

其可以用数组和链表实现。

队列代码如下:

/*************************************************************************
> File Name: queue.cpp
> Author:chudongfang
> Mail:1149669942@qq.com
> Created Time: 2016年06月30日 星期四 10时39分08秒
************************************************************************/

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include <algorithm>
#define INF 0x3f3f3f3f
#define LEN 5
using namespace std;
typedef long long ll;

int dequeue();
int enqueue(int x);
bool queue_empty();
bool queue_full();

int queue[LEN+1];
int head=1,tail=1;
int main(int argc,char *argv[])
{
enqueue(1);
for(int i=1;i<=LEN;i++)  printf("%d ",queue[i]);
printf("\nhead=%d\ntail=%d\n\n",head,tail);

enqueue(2);
for(int i=1;i<=LEN;i++)  printf("%d ",queue[i]);
printf("\nhead=%d\ntail=%d\n\n",head,tail);

enqueue(3);
for(int i=1;i<=LEN;i++)  printf("%d ",queue[i]);
printf("\nhead=%d\ntail=%d\n\n",head,tail);

printf("%d\n",dequeue());
for(int i=1;i<=LEN;i++)  printf("%d ",queue[i]);
printf("\nhead=%d\ntail=%d\n\n",head,tail);

enqueue(1);
for(int i=1;i<=LEN;i++)  printf("%d ",queue[i]);
printf("\nhead=%d\ntail=%d\n\n",head,tail);

enqueue(2);
for(int i=1;i<=LEN;i++)  printf("%d ",queue[i]);
printf("\nhead=%d\ntail=%d\n\n",head,tail);

enqueue(3);
for(int i=1;i<=LEN;i++)  printf("%d ",queue[i]);
printf("\nhead=%d\ntail=%d\n\n",head,tail);

return 0;
}

int enqueue(int x)//入队
{
if(queue_full())
{
printf("the queue is full!\n");
return 0;
}
queue[tail]=x;
if(tail==LEN)
tail=1;
else
tail++;
}

int dequeue()//出队
{
if(queue_empty())
{
printf("the queue is empty!");
return 0;
}

int x=queue[head];
if(head==LEN)
head=1;
else
head++;
return x;
}

bool queue_empty()//判断是否为空
{
if(tail==head)  return true;
else            return false;
}

bool queue_full()//判断是否满
{
if(head==tail+1||head==1&&tail==LEN)   return  true;
else               return  false;
}


栈代码如下:

/*************************************************************************
> File Name: stack.cpp
> Author:chudongfang
> Mail:1149669942@qq.com
> Created Time: 2016年06月30日 星期四 10时28分24秒
************************************************************************/

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int push(int key);
bool stack_empty();
int pop();
int stack[100];
int top=0;
int main(int argc,char *argv[])
{
memset(stack,0,sizeof(stack));
push(1);
for(int i=1;i<=10;i++)
printf("%d",stack[i]);
printf("\ntop=%d\n",top);
push(3);
for(int i=1;i<=10;i++)
printf("%d",stack[i]);
printf("\ntop=%d\n",top);

printf("pop=%d",pop());

return 0;
}
int push(int key)//入栈
{
top++;
stack[top]=key;
}

bool stack_empty()//判断栈是否为空
{
if(top==0)   return true;
else         return false;
}

int pop()//出栈
{
if(stack_empty())
{
printf("the stack is empty!");
return 0;
}
else
return stack[top--];
}


链表:

双向链表,单向链表,循环链表。

其与数组不同的是,其在内存中不连续,用指针链接起来

指针和对象的实现

1.对象的多数组表示:

对象的每一个属性使用一个数组表示,可以用来表示
一组有相同属性的对象。

一个对象的所有属性的数组下标相同

key[]储存其关键值
next[]储存下一个节点位置
prev[]储存上一个节点位置

具体代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;

int main(int argc,char *argv[])
{
//该数组链表用来储存9->1->3
int arry[20];

memset(arry,0,sizeof(arry));
int head=3;

arry[3]=9;   //key
arry[3+1] =7;//next
arry[3+2] =0;//prev

arry[7]   =1;
arry[7+1] =14;
arry[7+2] =3;

arry[14]  =3;
arry[14+1] =0;
arry[14+2] =7;

for(int i=1;i<=19;i++)
printf("%d ",arry[i]);

return 0;
}


2.对象的单数组表示

在一个数组中指针仅仅是该对象所在的第一个储存单元的地址,
要访问对象其他储存单元可以在指针上加上一个偏移量。

例如keynext prev对应的偏移量分别为0,1,2

则访问其时只需根据偏移量找到其元素

下面看例子的对应代码:

/*************************************************************************
> File Name: single_attay.cpp
> Author:chudongfang
> Mail:1149669942@qq.com
> Created Time: 2016年06月30日 星期四 11时08分58秒
************************************************************************/

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include <algorithm>
#define INF 0x3f3f3f3f
#define N 6
using namespace std;
typedef long long ll;

int main(int argc,char *argv[])
{
//该数组链表用来储存9->1->3
int next
;//下一个节点位置
int key
;//关键值
int prev
;//上一个节点位置
int head;
memset(next,0,sizeof(next));
memset(key,0,sizeof(key));
memset(prev,0,sizeof(prev));
head=3;

key[3] =9;
next[3]=5;

key[5] =1;
next[5]=2;
prev[5]=3;

prev[2]=5;
key[2] =3;

for(int i=1;i<N;i++)
printf("%d ",next[i]);
printf("\n");
for(int i=1;i<N;i++)
printf("%d ",key[i]);
printf("\n");
for(int i=1;i<N;i++)
printf("%d ",prev[i]);

return 0;
}


对象的分配与释放

用一个头节点为free的链表(自由表),表示其空余的空间,
然后对自由表进行操作,进行空间的分配与释放。

来看代码:

/*************************************************************************
> File Name: 10.3_objetc.cpp
> Author:chudongfang
> Mail:1149669942@qq.com
> Created Time: 2016年06月30日 星期四 09时12分15秒
************************************************************************/

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include <algorithm>
#define INF 0x3f3f3f3f
#define N 6
using namespace std;

int _free=0;

int allocate_object(int next[],int key[],int prev[]);
void free_object(int x,int next[]);

typedef long long ll;

int main(int argc,char *argv[])
{
//该数组链表用来储存9->1->3
int next
;
int key
;
int prev
;
int head;
memset(next,0,sizeof(next));
memset(key,0,sizeof(key));
memset(prev,0,sizeof(prev));
head=3;

key[3] =9;
next[3]=5;

key[5] =1;
next[5]=2;
prev[5]=3;

prev[2]=5;
key[2] =3;

for(int i=1;i<N;i++)
printf("%d ",next[i]);
printf("\n");
for(int i=1;i<N;i++)
printf("%d ",key[i]);
printf("\n");
for(int i=1;i<N;i++)
printf("%d ",prev[i]);
printf("\nfree=%d\n",_free);

_free=1;//空链表头节点
next[1]=4;
printf("\n\n");
for(int i=1;i<N;i++)
printf("%d ",next[i]);
printf("\n");
for(int i=1;i<N;i++)
printf("%d ",key[i]);
printf("\n");
for(int i=1;i<N;i++)
printf("%d ",prev[i]);
printf("\nfree=%d\n",_free);

int temp=allocate_object(next,key,prev);
if(temp==0)   printf("无可用的节点!\n");
else
printf("\n\n%d可用",temp);//返回一个空的节点
printf("\nfree=%d\n\n\n\n",_free);

free_object(5,next);//释放节点5后的情况

for(int i=1;i<N;i++)
printf("%d ",next[i]);
printf("\n");
for(int i=1;i<N;i++)
printf("%d ",key[i]);
printf("\n");
for(int i=1;i<N;i++)
printf("%d ",prev[i]);
printf("\nfree=%d\n",_free);

return 0;
}
int allocate_object(int next[],int key[],int prev[])//根据空链表,返回一个可用的节点
{
if(free==0)   return 0;
else
{
int x=_free;
_free=next[x];
return x;
}
}

void free_object(int x,int next[])//释放一个节点,并把其添加到空链表里
{
next[x]=_free;
_free=x;
}


其实可以多个链表共有一个自由表,而且多个链表和自由表位置上
可能交错在一起,不过一个位置只能属于一个链表。

有根树的表示:

二叉树:

一个二叉树包括其父节点指针,指向左儿子节点的指针和
指向右儿子节点的指针还有其卫星数据。

父节点为NULL的表示其为根节点
如果没有左儿子,左儿子节点为NULL,没有右儿子,则右儿子节点为空。

多叉树:

利用左孩子右兄弟表示法:
每个节点都包含一个父节点指针p,且T.root指向树T的根节点。

其含有另外两个节点:

1.x.left-child指向节点x最左边的孩子节点

2.x.right-sibling指向x右侧的兄弟

如果节点没有孩子节点,则x.left-child为NULL
如果节点x是其父节点的最右孩子,则x.right-sibling为NULL
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: