初识数据结构

数据结构顾名思义就是一堆数据的组织方式,以方便后续的存取和操作,且好的算法离不开高效管理数据的方法。

数据结构的三要素:

1. 数据集合。通过数据对象的本体(如数组和结构体)保存数据

2. 操作。对数据集合的操作,如插入、存取、查找、以及修改等

3. 规则。保证数据集合按照一定规矩来操作、管理和存取,如以何种顺序存取数据元素

 

在此介绍几种线性数据结构:

一、栈(Stack)

说明:用于临时保存数据,且按照后入先出的规则管理数据集合,在许多递归式的数学解题中都可应用栈来实现。

操作:

1. push(x) : 在栈顶部添加元素

2. pop() : 从栈顶取数据

3. isEmpty() : 栈是否为空

4. isFull() : 栈是否已满

用数组实现栈的代码:

 1 init()
 2     top = 0
 3 
 4 isEmpty()
 5     return top == 0
 6 
 7 isFull()
 8     return top >= Max -1
 9 
10 push(x)
11     if isFull()
12         error(overwrite)
13     S[++top] = x 
14 
15 pop()
16     if isEmpty()
17         error(overread)
18     return S[top--]
View Code

 

二、队列(Queue)

说明:队列是一个等待处理的数据行列,当希望按照数据抵达的先后顺序来处理数据时会用到,其按照先入先出的规则管理数据。在许多消息队列或消息系统中都有所应用,往往作为两个系统或进程间的数据缓冲区,可实现较好的用户体验。

操作:

1. enqueue(x) : 在队列末尾添加元素

2. dequeue() : 从队头中取出元素

3. isEmpty() : 队列是否空

4. isFull() : 队列是否满

队列可区分为线形和环形,但是线形的队列容易导致部分空间被浪费(因每次从队头中取元素使得head加1,若要防止这一情况需让head时常保持在0,即每次执行完dequeue后应让数据整体向数组开头移动,但这将增加复杂度),而环形队列能有效避免该问题。

环形缓冲区由一维数组构成,指示队列范围的head和tail指针在超出数组范围时重新从数组开头开始循环,即如果指针加1之后超出了数组范围,就重新置为0,其代码实现如下:

 1 init()
 2     head = tail = 0
 3 
 4 isEmpty()
 5     return head == tail
 6 
 7 isFull()
 8     return head == (tail + 1) % MAX
 9 
10 enqueue(x)
11     if isFull()
12         error(overwrite)
13     Q[tail] = x
14     if tail + 1 = MAX
15         tail = 0
16     else
17         tail++
18 
19 dequeue()
20     if isEmpty()
21         error(overread)
22     x = Q[head]
23     if head + 1 = MAX
24         head = 0
25     else
26         head++
27     return x
View Code

 

三、链表(List)

链表主要由结构体来实现,在C++中即由多个节点(node)来构成,每个节点由指针域和数据域组成,能够高效的在链表特定位置进行插入或删除操作,同时避免内存空间浪费(需要多少就申请多少)。此外,链表基本数据结构是实现高等数据结构的基础。

链表有许多不同的形式,如单向链表、双向链表、环形链表以及多个前驱或后驱节点的链表。在此仅介绍双向链表

操作:
1. insert(x) : 在链表中添加含有键值x的节点

2. delete(x) : 删除第一个含有键值x的节点

3. deleteFirst : 删除链表的表头节点

 4. deleteLast : 删除链表的表尾节点

代码实现如下:

 1 // 节点
 2 struct Node {
 3     int key;
 4     Node *prev, *next;
 5 };
 6 
 7 // 初始化
 8 Node *begin;
 9 void init() {
10     begin = (Node *) malloc (sizeof(Node));
11     begin->next = begin;
12     begin->prev = begin;
13 }
14 
15 // 插入元素
16 void insert (int key) {
17     Node *x = (Node *)malloc(sizeof(Node));
18     x->key = key;
19     //在头节点后插入元素
20     x->next = begin->next;
21     begin->next->prev = x;
22     begin->next = x;
23     x->prev = begin;
24 }
25 
26 // 搜索元素
27 Node* listSearch(int key) {
28     Node *current = begin->next;
29     while (current != begin && current->key != key)
30         current = current->next;
31     return current;          
32 }
33 
34 //删除元素
35 void deleteNode(Node* t) {
36     if (t ==begin) return;    //头节点不作处理
37     t->prev->next = t->next;
38     t->next->prev = t->prev;
39     free(t);
40 }
41 
42 void deleteFirst() {
43     deleteNode(begin->next);
44 }
45 
46 void deleteLast() {
47     deleteNode(begin->prev);
48 }
49 
50 void deleteKey (int key) {
51     deleteNode(listSearch(key));
52 }

 

posted @ 2017-07-30 18:00  zmlgo  阅读(437)  评论(0编辑  收藏  举报