1 / 39

软件技术基础

段景山. 软件技术基础. 线性结构. 制作 主讲. 段景山. 栈结构. 2 、堆栈 stack. 栈是特殊的线性表,仅在表的一端进行插入或删除操作. 出栈. 入栈. 栈顶. an. 是抽屉一类物理实体的逻辑抽象 类似仓库、抽屉的结构. a2. 栈底. a1. 特点:( 1 )对栈内数据的操作总在栈顶进行 ( 2 )数据进栈称为“压入” push ( 3 )数据出栈称为“弹出” pop ( 4 )遵循“后进先出”的原则 LIFO. 用数组实现栈. 2.1 用数组实现栈. 栈顶元素 所在位置. a[max].

Download Presentation

软件技术基础

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 段景山 软件技术基础 线性结构 制作 主讲 段景山

  2. 栈结构 2、堆栈 stack 栈是特殊的线性表,仅在表的一端进行插入或删除操作 出栈 入栈 栈顶 an 是抽屉一类物理实体的逻辑抽象 类似仓库、抽屉的结构 ... a2 栈底 a1 特点:(1)对栈内数据的操作总在栈顶进行 (2)数据进栈称为“压入”push (3)数据出栈称为“弹出”pop (4)遵循“后进先出”的原则LIFO

  3. 用数组实现栈 2.1用数组实现栈 栈顶元素 所在位置 a[max] a[0]为栈底,top为栈顶 new_one ... ... (1)定义 a[top] 栈顶 typedef struct stack_type{ elemtype data[MAXNUM]; int top; }stack_type; ... a2 a[1] a1 a[0] (2)压入 push 当新元素入栈时,栈顶上移,新元素放在栈顶。 stack.top = stack.top + 1; stack.data[stack.top] = new_one;

  4. 用数组实现栈 (3)弹出 pop a[max] 从栈顶移出一个数据。 out 栈顶 a[top] 栈顶元素拷贝出栈,栈顶下移 ... out = stack.data[stack.top]; stack.top = stack.top - 1; ... a2 elemptype pop(stack_type *stack){ elemtype out; if(stack->top <= 0) error(3); else{ out = stack->data[stack->top]; stack->top = stack->top -1; } return out; } a[1] a1 a[0]

  5. 用数组实现栈 (4)栈空判断 stack.top == 0 stack.top a[0] stack.top < 0 栈顶元素所在位置 栈满判断:stack.top >= MAXNUM - 1; (5)置栈空 stack.top = -1;

  6. proc B( ) ...... ...... call C( ) ...... proc C( ) ...... ...... ...... proc A( ) ...... call B(); ...... 用数组实现栈 (6)栈的应用 例 程序的嵌套,中断的嵌套 程序C 程序B 程序A

  7. proc B( ) ...... ...... call C( ) ...... proc C( ) ...... ...... ...... proc A( ) ...... call B( ); ...... 用数组实现栈 (6)栈的应用 程序的嵌套,中断的嵌套 程序C 程序C 程序B 程序A 程序B 程序A

  8. an a1 a2 …… 用链表实现栈 • 2.2用链表实现栈 入栈 出栈 head top 栈顶在 表头 (1)定义 typedef struct lstack_type{ node_type * top; int length; }lstack_type;

  9. 用链表实现栈 (2)压入push void push(stack, new_node){ new_node->next = stack->top; stack->top = new_node; stack->length ++; } …… a1 stack->top (3)弹出pop node_type * pop(stack){ node_type* out; out = stack->top; stack->top = stack->top->next; stack->length --; return out; } new

  10. 用链表实现栈 (4)栈空判断 int empty(stack){ if(stack.top == NULL) return YES; else return NO; } stack.top == NULL; (5)置栈空 能否简单的使用 stack.top = NULL ? 如果栈中还有链点,必须逐个将链点占用的空间释放 void clean(stack){ node_type * temp; while( ! empty(stack)){ temp = pop(stack); free(temp);} } 1、逐个将链点弹出 2、释放链点空间

  11. 队列 • 3、队列 • 类似于排队机制的结构 • 队列是特殊的线性表, • 节点的插入仅限于在表尾进行, • 节点的删除仅限于在表头进行 入队 出队 队尾 队头

  12. 队列 • 特点: • (1)对队列的操作在表的两端进行 • (2)仅在队尾加入节点——入队enqueue • (3)仅在队首移出节点——出队dequeue • (4)遵循“先进先出”的原则——FIFO 出队 入队 队头 队尾

  13. 用数组实现队列 • 3.1用数组实现队列 • (1)定义 a[0] a[1] ... a[n] ... MAX 队首 队尾 rear front typedef struct queue_type{ elemtype data[MAXNUM]; int front; int rear; }queue_type;

  14. rear front 用数组实现队列 • (2)入队与出队 移元素? 移队首、尾指针 入队 出队 入队 出队 入队 数组空间溢出而使操作出错

  15. front rear ( ) % MAXNUM 用循环数组实现队列 • 3.2用循环数组实现队列 入队 rear = rear + 1 % 整除取余 设MAXNUM = 5,rear=4 则新元素加入队列后: rear =(4+1)% 5=0,新元素放在a[0]内

  16. front front rear rear 用循环数组实现队列 队列元素位置?

  17. rear front front 用循环数组实现队列 • 队空条件 • 队满条件 front == rear 如果rear表示队尾节点的位置则有一个节点的队列的指针情况和队空时相同 front rear rear (rear + 1) % MAXNUM = = front

  18. rear front front 用循环数组实现队列 • 队空条件 • 队满条件 front == rear 定义:rear为指向队尾下一个可存放节点的位置 队列满时还有一个空位置 rear (rear + 1) % MAXNUM = = front

  19. front rear 用循环数组实现队列 • 入队算法 队列已满? void enqueue(queue,new_one){ if( (queue->rear + 1) % MAXNUM == queue->front) error(1); else{ queue->data[queue->rear] = new_one; queue->rear = (queue->rear +1) % MAXNUM; } } 队列尾部放入新节点 队尾指示向后移动一格

  20. front rear 用循环数组实现队列 • 出队算法--课堂练习 elemtypedequeue(queue){ elemtype out; if( queue->rear == queue->front) error(2); else{ out =queue->data[queue->front]; queue->front = (queue->front +1) % MAXNUM; } return out; }

  21. front 用循环数组实现队列 • 思考:在循环队列的第K个元素后插入一个新元素--插队 • 如何确定aK的位置? • 如何搬移节点,以腾出空位放入新元素? rear

  22. an a1 a2 …… 用链表实现队列 • 3.3用链表实现队列 front rear (一)定义 typedef struct lqueue_type{ node_type * front; node_type * rear; int length; }

  23. an a1 a2 …… 用链表实现队列 • (二) 入队 • 新链点插入到队尾 • 注意:队列为空时,rear和front都要指向新元素 • (三) 出队 • 删除队首链点 • 注意:当队列被删空时,rear指针要置空 new_node->next = NULL; list->rear ->next = new_node; rear front temp = list->front; list->front = list->front->next;

  24. 元素 字符 字符串中字符的先后次序 元素间的关系 串结构 • 4、串 串即字符串: 由零到多个字符组成的连续有限序列 • 串是一种线性结构 • 串符合线性表的特性(特别是顺序表) • 字符串的特殊性在于对串有一些特殊的操作 线性

  25. 串结构 • 4.1访问操作 • 基本访问: • 根据字符在串中位置获得字符; • 根据字符获得它在串中位置 • 遍历:逐个访问串中字符 • 部分访问(求子串): • 获得串中指定位置开始的多个元素 • 获得子串在串中的位置 课堂练习: 以姓名为例分别给出各种操作应用示例。 如: Duan Jingshan 取得J所在的位置可以获得姓的长度

  26. 串结构 • 4.2插入 • 基本插入:在串中指定位置插入一个字符 • 子串插入:在串中指定位置插入多个字符 • 4.3删除 • 基本删除:在串中指定位置删除字符 • 子串删除:在串中指定位置删除多个字符 • 4.4其它操作 • 串连接:一个串连在另一个串的后面,形成新串 • 求串长、串比较、子串替换 ...... 串的操作是文字处理的基础

  27. 串结构 • 4.5串的实现 • (1)字符数组(用数组实现串) • 紧缩格式: • 数组每一个单元类型都是字符型,可放入一个字节的字符 • 非紧缩格式: • 数组的单元不是字符型——2~4个字节 a[0] a[0] char a[4]; long a[4]; D D a[1] a[1] u u 共16字节 a[2] a[2] 共4字节 a a a[3] a[3] n n

  28. 串结构 • (2)字符链表(用链表实现串) • 链表的每个链点的元素域放入一个字符 • 操作方便,但空间开销大 • 链点元素域占一个字节 • 链点指针域占四个字节 • 开销为4/5 s t u d e n t

  29. 二维数组(矩阵) j • 5、二维数组 • 行关系,列关系均是线性关系 • 5.1二维数组的顺序存放 • (一)行优先存放 • 计算aij的存放位置: ... a11 a12 a21 ... i aij ... amn ... a11 a12...a1na21a22...ai1 ai2 ...ain...am1 am2 ...amn 设每个元素占据S个存储单元 Loc(aij) = Loc(a11) + (( i - 1)*n + (j - 1))*S 计算前面有多少个元素

  30. 二维数组 • (二)列优先存放 a11 a21...am1a12a22...am2a1j a2j ...aii...a1n a2n ...amn Loc(aij) = Loc(a11) + (( j - 1)*m + (i - 1))*S j ... a11 a12 a21 ... i aij ... amn ...

  31. data 行指针 列指针 二维数组 • 5.2矩阵的链接存储 十字链表法 a11 a12 a1i a1n a21 a22 ...... a31 a32 ...... am1 am2

  32. 二维数组 ... 1 • 5.3矩阵的压缩存储 • (1)对称矩阵,三角矩阵的压缩 • 对称矩阵:a[ i , j ] = a[ j , i ] • 三角矩阵:上三角为0,或下三角为0 只存储上或下三角内的元素,节约近一半的存储空间 3 4 0 5 2 6 2 4 3 7 1 5 3 6 5 a11 a21a22a31a32a33a41…aii...an1 an2 ...ann

  33. 二维数组 ... • (1)对称矩阵,三角矩阵的压缩 1 3 4 0 5 2 6 2 4 3 7 1 5 3 6 5 a11 a21a22a31a32a33a41…aii...an1 an2 ...ann 1+2+3+…+(i-1) i >= j 时,元素位于下三角 Loc(aij) = Loc(a11) + ( i ( i - 1) / 2 + ( j - 1))*S i < j 时,元素位于上三角 Loc(aij) = Loc(a11) + ( j ( j - 1) / 2 + ( i - 1))*S

  34. aij 行值,列值,元素值 二维数组 • (2)稀疏矩阵 • 矩阵中的非零元素很少,分布没有规律 • 利用三元存储法 • 先形成三元矩阵 • 再按照行优先顺序方式存储。 行数 列数 第一行 非零元素个数 第一个非零元素 行值 列值 元素值 = AMN 第二个非零元素 行值 列值 元素值 ... ...

  35. 二维数组 • 稀疏矩阵压缩存储例 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 = X48 0 0 6 0 0 0 5 0 0 0 3 0 0 0 0 0 4 8 5 行数 列数 非零元素个数 1 1 1 = A63 2 1 4 6 3 2 5 3 7 4 1 3 a[18] = {4,8,5,1,1,1,2,4,1,3,2,6,3,7,5,4,1,3}

  36. 二维数组 • 稀疏矩阵三元组定义 • 1)定义三元组元素 • 2)定义三元组 typedef struct tuple3tp{ int row_num; /*行号*/ int col_num; /*列号*/ elemtype value; /*元素值*/ } tuple3tp typedef struct tuple3{ int row; /*行数*/ int col; /*列数*/ int num; /*非零元素个数*/ tuple3tp data[ MAXNUM];/* 三元组*/ }tuple3;

  37. 上机习题:稀疏矩阵求转置 void transposition(tuple3 * a, tuple3 * b) { int col, i,num; b.row = a.col, b.col = a.row, b.num = a.num; num = 0; for(col = 0; col < a.col ; col ++){ for(i = 0; i < a.num; i ++){ if( a[ i ].col_num = = col){ b[ num ].col_num = a[ i ].row_num; b[ num ].row_num = a[ i ].col_num; b[ num ].value = a[ i ].value; num += 1; } }} } 转置后的矩阵仍以三元组法,行优先存放 注意:部分“.”在实际程序中应该为“->” 思考:稀疏矩阵相加

  38. 小结 数据逻辑结构 数据结构 数据存储结构 算法 用数组实现(顺序XX) 线性结构、栈、队列、串 用链表实现(链接XX) 顺序表与线性链表(单链表、双链表) 顺序栈与链栈(应用--回溯性) 与链队列 与 循环链表 ? 顺序队列 循环队列 二维数组的存储(行优先、列优先,定位) 数组的压缩(压缩定位,三元组法)

  39. 作业 • 教材71页12、13、14

More Related