算法笔记——七

算法笔记——七

  • 第七章
    • 7.1 栈的应用
      • 1.clear:
      • 2.size:
      • 3.empty:
      • 4.push:
      • 5.pop:
      • 6.top:
      • codeup_1918 简单计算器
        • 1.中缀表达式转后缀表达式
        • 2.计算后缀表达式
    • 7.2 队列的应用
      • 1.clear
      • 2.size
      • 3.empty
      • 4.push
      • 5.pop
      • 6.get_front
      • 7.get_rear
    • 7.3 链表处理
      • 7.3.1 链表的概念
      • 7.3.2.使用malloc或new运算符为链表节点分配内存空间
        • 1.malloc
        • 2.new
        • 3.内存泄漏
          • 1.free(p )(对应于malloc)
          • 2.delete(p )(对应于new)
      • 7.3.3.链表的基本操作
        • 1.创建链表
        • 2.查找元素
        • 3.插入元素
        • 4.删除元素
      • 7.3.4.静态链表
        • PAT_A1032 Sharing
        • 静态链表通用解题步骤
        • PAT_A1052 Linked List Sorting

第七章

7.1 栈的应用

栈没有元素时令TOP为-1

1.clear:

TOP置为-1

2.size:

栈内元素的数为TOP+1

3.empty:

仅当TOP=-1时栈空,返回true

4.push:

先TOP加1,再把x存入TOP指向的位置

5.pop:

直接将栈顶指针TOP减1

6.top:

st[TOP]即为栈顶元素
pop()和top()函数之前必须先试用empty()函数判断栈是否为空
STL中没有实现栈的清空,清空栈可以用一个while循环反复pop处元素直到栈空,更长用的方法是重新定义一个栈以变相实现栈的清空

codeup_1918 简单计算器

1.中缀表达式转后缀表达式

  1. 操作符栈临时存放操作符,数组或者队列存放后缀表达式
  2. 碰到操作数加入后缀表达式(队列)
  3. 碰到操作符(op),将其优先级与操作符栈的栈顶操作符优先级比较
  • op优先级高于栈顶操作符,压入操作符栈
  • op优先级小于等于栈顶操作符优先级,操作符栈的操作符不断弹出到后缀表达式,直到op优先级高于栈顶操作符的优先级
  1. 重复上述操作,直到扫描完中缀表达式。之后若操作符栈中仍有元素,则将它们依次弹出至后缀表达式中。
  • 如果出现括号,如果左括号,压入操作符栈,如果右括号,就把操作符栈里的元素不断弹出到后缀表达式直到碰到左括号。
  • 操作符优先级具体实现用map建立操作符和优先级的映射,优先级用数字表示

2.计算后缀表达式

  1. 如果是操作数,压入栈
  2. 如果是操作符,连续弹出两个操作数(后弹出的是第一个操作数),然后进行操作符的操作,生成的新操作数压入栈中。反复直到后缀表达式扫描完毕,最终答案为栈中元素。

当 cin 读取数据时,它会传递并忽略任何前导白色空格字符(空格、制表符或换行符)。一旦它接触到第一个非空格字符即开始阅读,当它读取到下一个空白字符时,它将停止读取。可以输入 “Mark” 或 “Twain”,但不能输入 “Mark Twain”,因为 cin 不能输入包含嵌入空格的字符串。故引入getline 函数如下所示:getline(cin, inputLine);其中 cin 是正在读取的输入流,而 inputLine 是接收输入字符串的 string 变量的名称。

7.2 队列的应用

队首指针front指向队首元素前一个位置,队尾指针rear指向队尾元素

1.clear

使用数组实现队列,初始状态为front = -1,rear = -1。

2.size

rear - front

3.empty

front == rear

4.push

先把rear加1,再存放到rear指向的位置

5.pop

队首指针加1

6.get_front

队首指针指向 队首元素的前一个元素,因此front+1才是队首元素的位置

7.get_rear

直接访问rear的位置
pop(),get_front(),get_rear()函数之前先要用empty()判断
STL中没有实现队列的清空,方法同栈

7.3 链表处理

7.3.1 链表的概念

struct node{
    typename data;
    node*  next;
 };

7.3.2.使用malloc或new运算符为链表节点分配内存空间

1.malloc

typename* p = (typename*)malloc(sizeof(typename));
node* p = (node*)malloc(sizeof(node));
int* p = (int*) malloc(1000000*sizeof(int)); // 申请较大的动态数组会返回空指针NULL 

申请成功通过指针p来访问,申请失败,返回空指针NULL

2.new

typename* p = new typename;
node* p = new node;
int* p = new int[1000000];

3.内存泄漏

1.free(p )(对应于malloc)

两个效果:

  1. 释放指针变量p所指向的内存空间
  2. 将指针变量p指向空地址NULL
2.delete(p )(对应于new)

7.3.3.链表的基本操作

1.创建链表

malloc或者new节点,然后把每个节点的next只想下一个节点的地址
用for循环建立链表:代码自己手写

2.查找元素

返回count值为链表中元素x的个数

3.插入元素

在第3个位置插入元素4的意思是插入完成之后第3个位置的元素就是4

4.删除元素

7.3.4.静态链表

实现原理是hash,通过建立结构体数组,并令数组的下标直接表示结点的地址,来达到直接访问数组中元素就能访问结点的效果。静态链表不需要头结点。

struct Node{
    typename data;
    int next;
}node[size];
//eg:为什么是node[1] = 2, 而不是node[1].next = 2呢?
node[11111] = 22222;
node[22222] = 33333; 
node[33333] = -1;

把结构体类型名和结构体变量名设成不同的名字(Node和node)是由于静态链表是由数组实现的,就有可能需要对其进行排序,如果结构体类型名和结构体变量名相同,sort函数就会编译出错,因此尽量不要把结构体类型名和结构体变量名变成相同的名字。

PAT_A1032 Sharing

静态链表通用解题步骤

// 1. 定义静态链表
struct Node{
    int address;
    typename data;
    int next;
    XXX; // 结点性质,例如flag
}node[100010];
// 2. 初始化
for(int i = 0; i < maxn; i++){
    node[i].XXX = 0; // 0即false
}
// 3.题目一般给出首结点地址,根据首地址遍历整条链表,同时对结点性质XXX进行标记、并对有效结点个数进行计数
int p = begin, count = 0;
while(p != -1){
    XXX = 1;
    count++;
    p = node[p]->next;
}
// 4. 地址映射hash使得数组下标不连续,一般需要对数组进行排序把有效结点移到数组左边,用之前定义的XXX来帮忙。
bool cmp(Node a, Node b){
    if(a.XXX == -1 || b.XXX == -1){ // 至少有一个是无效结点,就把它放到数组后面
        return a.XXX > b.XXX;
    }else{
        // 第二级排序
    }
}

PAT_A1052 Linked List Sorting

你可能感兴趣的:(算法笔记)