热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

读《数据结构》14章[线性结构]

2016.06.07–06.30读《数据结构》(严蔚敏吴伟明)“1-4章”的个人笔记。06.071与数据结构相关的理解对数据结构的理解࿰

2016.06.07 – 06.30
读《数据结构》(严蔚敏 吴伟明)“1-4章”的个人笔记。

06.07


1 与数据结构相关的理解

对数据结构的理解(编程语言层面)。数据结构是相互之间存在一种或多种特定关系的数据元素的集合。

例 – 线性链表。

/* 描述数据元素的类型 */
typedef struct _link_list {char ch;int i;struct _link_list *pn;
}LinkList;/* 描述数据元素之间关系的代码 */
...

用LinkList定义一个数据对象(变量)就得到一个数据元素,用LinkList定义多个数据对象就得到数据元素的集合;组织各个数据元素在内存中的存储关系(在内存中连续或者不连续存储)及各个数据元素间(被操作)的联系(如pn指向另外一个数据元素)就得到了各个数据元素之间的关系。

算法。算法是对特定问题求解步骤的一种描述。算法效率的度量需通过依据该算法编制的程序在计算机上运行(时)所消耗的时间来度量[代码的时间复杂度可作为算法执行效率的一种参考]。

时间复杂度。一般情况下,算法中基本操作重复执行的次数是问题规模n的一个函数f(n),算法的复杂度记作T(n) = O(f(n)),表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率是相同

06.08
f(n)的计算。对于不同的输入该算法有不同的执行次数时,可用平均值作为f(n)的值;有时各种输入数据输入的概率难以确定,所以更可行的方法是使用该算法最坏执行次数的值作为f(n)的值。

算法的存储空间 复杂度。空间复杂度S(n) = O(f(n)),其中n为问题规模。一个上机执行程序除了需要存储空间来寄存本身所用指令、常数、变量和输入数据外,也需要一些对数据进行操作的工作单元和存储一些为实现计算所需信息的存储空间。若输入数据所占空间只取决于问题本身,和算法无关,则只需要分析除输入和程序之外的额外空间。


Part-I 线性结构

线性结构的特点:在数据元素的非空有限集合中,(1) 存在唯一的一个被称做“第一个”的数据元素;(2) 存在唯一的一个被称做“最后一个”的数据元素;(3) 除了第一个外,集合中的每个数据元素均只有一个前驱;(4) 除最后一个外,集合中每个数据元素均只有一个后继。


2 线性表

线性表。一个线性表是n个数据元素(记录,可以有若干个数据项)的有限序列,其长度可变。[含有大量记录的线性表被称为文件]


2.1 顺序表

线性表的顺序表示 – 顺序表。线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。

例 - 用C语言来实现一个简单的顺序表。先为顺序表动态分配以元素大小为单位的n个空间单元;若往顺序表中插入一个元素时若超过了当前所分配的空间则往当前空间中追加m个空间单元

06.14
[1] 代码简单实现
sequence_list.c

/* sequence_list.c* 实现一个满足线性表的顺序表的定义的顺序表及一些相关的简单操作* 2016.06.13 - 06.14*/
#include
#include /* 函数退出状态 */
#define MALLOCFAILE -1 // 分配空间失败
#define OK 0 // 程序正常返回值
#define FAILE 1 // 函数返回失败/* 线性表的顺序表动态分配顺序存储结构 */
#define LIST_INIT_SIZE 100 // 线性表存储空间的初始分配量
#define LIST_INCREMENT 10 // 线性表存储空间的分配增量
typedef char ElemType;
typedef struct {ElemType *pelem; // 线性表存储空间基址int len; // 线性表长度int lsize; // 线性表当前分配的存储空间
}SqList;/* 为线性表的顺序表创建存储空间 */
int malloc_sq_list(SqList *psql)
{if (!psql) return FAILE;// 构造一个空(无值)的线性表psql->pelem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));if (!psql->pelem) exit(MALLOCFAILE);psql->len = 0;psql->lsize = LIST_INIT_SIZE;return OK;
}/* 释放线性表的顺序表的存储空间 */
void free_sq_list(SqList *psql)
{if (!psql || !psql->pelem) return ;free(psql->pelem);psql->pelem = NULL;psql->len = 0;psql->lsize = 0;
}/* 往线性表的顺序表中插入一个元素 */
int insert_elem2sq_list(SqList *psql, int i, ElemType elem)
{ElemType *newbase, *p, *q;if (!psql || !psql->pelem) return FAILE;// 在顺序线性表psql第i个位置之前插入新的元素elemif (i <1 || i > psql->len &#43; 1) return FAILE;if (psql->len >&#61; psql->lsize) {newbase &#61; (ElemType *)realloc(psql->pelem, \(psql->lsize &#43; LIST_INCREMENT) * sizeof(ElemType));if (!newbase) exit(MALLOCFAILE);psql->pelem &#61; newbase;psql->lsize &#43;&#61; LIST_INCREMENT;}q &#61; &psql->pelem[i - 1]; // 插入位置for (p &#61; &psql->pelem[psql->len - 1]; p >&#61; q; --p) {*(p &#43; 1) &#61; *q; // 插入位置及之后的元素后移}*q &#61; elem;&#43;&#43;psql->len;return OK;
}/* 将两个顺序表合并到另一个顺序表中 */
void merge_sq_list(SqList *psqla, SqList *psqlb, SqList *psqlc)
{// 已知顺序线性表psqla&#xff0c;psqlb的元素按值非递减排列// 归并psqla, psqlb得到的新顺序线性表psqlc的元素也按值非递减排列ElemType *pa, *pb, *pc;ElemType *pa_last, *pb_last;if (!psqla || !psqlb || !psqla->pelem || !psqlb->pelem) return ;pa &#61; psqla->pelem;pb &#61; psqlb->pelem;psqlc->lsize &#61; psqlc->len &#61; psqla->len &#43; psqlb->len;pc &#61; psqlc->pelem &#61; (ElemType *)malloc(psqlc->lsize * sizeof(ElemType));if (!pc) exit(MALLOCFAILE);pa_last &#61; psqla->pelem &#43; psqla->len - 1;pb_last &#61; psqlb->pelem &#43; psqlb->len - 1;while (pa <&#61; pa_last && pb <&#61; pb_last) {if (*pa <&#61; *pb) *pc&#43;&#43; &#61; *pa&#43;&#43;;else *pc&#43;&#43; &#61; *pb&#43;&#43;;}while (pa <&#61; pa_last) *pc&#43;&#43; &#61; *pa&#43;&#43;;while (pb <&#61; pb_last) *pc&#43;&#43; &#61; *pb&#43;&#43;;
}/* 简单测试以上各个函数 */
int main(void)
{int i, rv;ElemType elem;SqList psqla, psqlb, psqlc;i &#61; 1;elem &#61; 1;// 创建顺序线性表空间if ((rv &#61; malloc_sq_list(&psqla)) !&#61; OK || \(rv &#61; malloc_sq_list(&psqlb)) !&#61; OK ) {fprintf(stderr, "Create sequence list failed\n");exit(FAILE);}// 往顺序线性表中插入值insert_elem2sq_list(&psqla, i&#43;&#43;, elem&#43;&#43;);insert_elem2sq_list(&psqlb, i, elem);printf("%d %d\n", *psqla.pelem, psqlb.pelem[--i]);// 合并两个线性表merge_sq_list(&psqla, &psqlb, &psqlc);printf("%d %d\n", *psqlc.pelem, psqlc.pelem[i]);// 释放顺序线性表free_sq_list(&psqla);free_sq_list(&psqlb);free_sq_list(&psqlc);return 0;
}

06.15
-man realloc-
原型。void *realloc(void *ptr, size_t size);
功能。realloc函数将ptr所指向的内存块的大小改为size字节大小&#xff08;原内容不会被改变&#xff09;。如果新的大小大于原来的大小&#xff0c;新增的内存块不会被初始化。如果ptr为NULL&#xff0c;那么realloc相当于malloc&#xff08;size&#xff09;&#xff1b;如果size等于0并且ptr不为NULL&#xff0c;则该调用相当于free(ptr)。除非ptr为NULL&#xff0c;否则ptr必须是之前malloc()&#xff0c;calloc()或realloc()的返回值。如果指向的区域被移动&#xff0c;则原来的内存区域会被自动的free(ptr)。
返回值。realloc()函数返回一个指向新内存区域的指针&#xff0c;若请求失败则返回NULL。如果size等于0&#xff0c;NULL或者传递给free()函数过后的指针将被返回。如果realloc()失败&#xff0c;则原来的内存块将不变&#xff1b;它不会被释放或移除。

[2] 算法复杂度分析
insert_elem2sq_list具有重复&#xff08;循环&#xff09;的是元素的移动操作&#xff0c;最坏的情况是将元素插入到表中的第一个元素之前&#xff08;需要移动n个元素 – 假设表具有n个元素&#xff09;。insert_elem2sq_list的复杂度可用O(n)来表示。同理&#xff0c;合并俩链表的操作的时间复杂度也为O(n)。[《CSAPP》中有更细致的分析]

线性表的特点是逻辑关系相邻的两个数据元素在内存中存储位置也是相邻关系&#xff0c;因此可以用一个简单的、直观的公式来表示&#xff08;在C语言中也能够用简单的方式访问&#xff0c;如下标、偏移&#xff09;。然而这种存储结构也有一个弱点&#xff1a;在作插入或删除操作时&#xff0c;需要移动大量元素。


2.2 链表


(1) 线性链表

线性链表。线性链表的存储结构特点是各个逻辑关系相邻的数据元素既可以用连续的内存单元存储也可以用非连续的内存单元存储。[见链表的结点 —— 因为每个结点中只含有一个指针域&#xff0c;故而称这样的链表为线性链表或单链表]

链表的结点。为了表示线性链表中ai与ai&#43;1元素之间的逻辑关系&#xff08;ai&#43;1为ai的后继元素&#xff09;&#xff0c;ai除了要存储本身的信息外&#xff0c;还要存储ai&#43;1的地址信息&#xff08;指针域&#xff09;&#xff0c;ai中的这两部分信息被称为结点。

例 – 用C语言实现一个简单的单链表
06.17
[1] 代码简单实现
single_link_list.c

/* signle_link_list.c* 单链表线性表的简单表示和实现* 2016.06.15 - 06.17*/
#include <stdlib.h>
#include <stdio.h>/* 函数返回值 */
#define NK -1 // 函数未正常返回
#define OK 0 // 函数正常返回
#define NP 1 // 函数参数不合法
#define ME 2 // 空间分配失败/* 描述单链表的结构体类型 */
typedef char ElemType;
typedef struct _single_link_list_node {ElemType data; // 数据域struct _single_link_list_node *next; // 指针域
}SLNode, SLHead;/* 创建一个包含n个结点的单链表&#xff0c;每个结点的数据域为创建时结点的顺序 */
SLHead *create_single_link_list(unsigned n)
{unsigned i;SLHead *head;SLNode *pcn, *pln;i &#61; 0;if (n < 1) return NULL;// 头结点if (NULL &#61;&#61; (head &#61; (SLNode *)malloc(sizeof(SLNode)))) {fprintf(stderr, "head of link list malloc failed\n");exit(ME); // 退出本进程&#xff0c;进程用户空间被回收从而堆空间自然被回收}head->data &#61; 0;head->next &#61; NULL;pln &#61; head;// 单链表中的结点while (n--) {if (NULL &#61;&#61; (pcn &#61; (SLNode *)malloc(sizeof(SLNode)))) {fprintf(stderr, "%d th node malloc failed\n", &#43;&#43;i);exit(ME);}pcn->next &#61; NULL;pcn->data &#61; &#43;&#43;i;pln->next &#61; pcn;pln &#61; pcn;}return head;
}/* 释放具有n个结点的单链表 */
void free_single_link_list(SLHead *head)
{SLNode *pcn, *pnn;pcn &#61; pnn &#61; head;while (pcn) {pnn &#61; pnn->next;free(pcn);pcn &#61; pnn;}
}/* 往单链表中的第i个结点前插入一个元素 */
int insert_node2link_list(SLHead *head, unsigned i, ElemType e)
{int j;SLNode *pcn, *pnewn;if (!head) return NP;j &#61; 0;pcn &#61; head;while (pcn && j < i - 1) { // 寻找i - 1个结点pcn &#61; pcn->next;&#43;&#43;j;}if (!pcn || j > i - 1) return NK;if ((pnewn &#61; (SLNode *)malloc(sizeof(SLNode))) &#61;&#61; NULL) {fprintf(stderr, "insert %d element failed\n", e);return NK;}pnewn->data &#61; e;pnewn->next &#61; pcn->next;pcn->next &#61; pnewn;return OK;
}/* 合并两个单链表 */
/* 已知两个单链表元素按值非减排列 */
/* 归并两个链表得到新链表&#xff0c;新链表也按照值非递减排列 */
SLHead *merge_link_list(SLHead *heada, SLHead *headb)
{SLNode *la, *lb, *lc, *headc;if (!heada || !headb) return ;la &#61; heada->next;lb &#61; headb->next;headc &#61; lc &#61; heada;while (la && lb) {if (la->data <&#61; lb->data) {lc->next &#61; la;lc &#61; la;la &#61; la->next;} else {lc->next &#61; lb;lc &#61; lb;lb &#61; lb->next;}}lc->next &#61; la ? la : lb;free(headb);return headc;
}/* 输出单链表的所有元素 */
void print_link_list_node_value(SLHead *head)
{SLNode *p;if (!head) return;p &#61; head->next;while (p) {printf("%d ", p->data);p &#61; p->next;}printf("\n");
}/* 简单测试单链表 */
int main(void)
{int i;SLHead *ha, *hb, *hc;unsigned la_len, lb_len;la_len &#61; lb_len &#61; 7;if (NULL !&#61; (ha &#61; create_single_link_list(la_len)))print_link_list_node_value(ha);if (NULL !&#61; (hb &#61; create_single_link_list(lb_len)))print_link_list_node_value(hb);hc &#61; merge_link_list(ha, hb);print_link_list_node_value(hc);for (i &#61; 1; i < 15; &#43;&#43;i)insert_node2link_list(hc, i, i);print_link_list_node_value(hc);free_single_link_list(hc);return 0;
}

在shell下编译并运行single_link_list.c得以下结果&#xff1a;
这里写图片描述

[2] 复杂度分析
同顺序表&#xff0c;单链表的插入操作的时间复杂度为O(n)。合并单链表的时间复杂度也为O(n)。


(2) 循环链表

循环链表。循环链表的最后一个数据元素指向第一个数据元素&#xff08;其他同线性链表&#xff09;。


(3) 双向链表

双向链表。双向链表的结点中有两个指针域&#xff0c;该结点中的一个指针域指向后驱元素&#xff0c;一个指针域指向前趋元素。

例 — 用C语言实现一个简单的双向链表
06.22
double_link_list.c

/* double_link_list.c* 双向链表的简单描述* 2016.06.17 - 06.22*/
#include <stdio.h>
#include <stdlib.h>/* 函数返回值 */
#define NK -1 // 函数非正常返回
#define OK 0 // 函数正常返回
#define EP 1 // 参数不合法typedef char ElemType; // 双向链表中数据域中的数据类型
/* 描述双向链表的结构体 */
typedef struct _DulNode {ElemType dt;struct _DulNode *pr;struct _DulNode *pn;unsigned nm;
}DulNode, *DuLinkList;/* 创建双向链表 */
/* 结点中的数据域的值为结点被创建时的个数 */
DuLinkList create_dul_link_list(unsigned n)
{int i;DuLinkList head, ps, nt;if (NULL &#61;&#61; (ps &#61; (DulNode *)malloc(sizeof(DulNode)))) {exit(NK);}i &#61; 1;ps->pr &#61; NULL;ps->pn &#61; NULL;ps->dt &#61; i;head &#61; ps;ps->nm &#61; i;while (--n) {if (NULL &#61;&#61; (nt &#61; (DulNode *)malloc(sizeof(DulNode)))) {exit(NK);}ps->pn &#61; nt;nt->pr &#61; ps;nt->dt &#61; &#43;&#43;i;ps &#61; nt;head->nm&#43;&#43;;}ps->pn &#61; head;head->pr &#61; ps;return head;
}
/* 释放双向链表 */
void free_dul_link_list(DuLinkList dl)
{int i;unsigned n;DuLinkList pr, pn;if (!dl) return;n &#61; dl->nm;pr &#61; dl;pn &#61; dl->pn;for (i &#61; 1; i <&#61; n; &#43;&#43;i) {if (pr) {free(pr);pr &#61; pn;pn &#61; pn->pn;}}
}
/* 合并俩双向链表 */
DuLinkList merge_dul_link_list(DuLinkList dla, DuLinkList dlb)
{// 已知双向链表dla和dlb按值递增排列// 将dla和dlb合并成一个双向链表&#xff08;递增排列&#xff09;unsigned dla_nm, dlb_nm;DuLinkList dlc, head, tail;if (!dla || !dlb) return NULL;dla_nm &#61; dla->nm;dlb_nm &#61; dlb->nm;if (dla->dt <&#61; dlb->dt) {dlc &#61; head &#61; dla;dla &#61; dla->pn;dla_nm--;} else {dlc &#61; head &#61; dlb;dlb &#61; dlb->pn;dlb_nm--;}head->nm &#61; dla_nm &#43; dlb_nm &#43; 1;while (dla_nm && dlb_nm) {if (dla->dt <&#61; dlb->dt) {dlc->pn &#61; dla;dla->pr &#61; dlc;dlc &#61; dla;dla &#61; dla->pn;dla_nm--;} else {dlc->pn &#61; dlb;dlb->pr &#61; dlc;dlc &#61; dlb;dlb &#61; dlb->pn;dlb_nm--;}}tail &#61; dla_nm ? dla : dlb;dlc->pn &#61; tail;tail->pr &#61; dlc;dlc &#61; tail;dlc->pn &#61; head;head->pr &#61; dlc;return head;
}/* 打印双向链表中的内容 - 验证 */
void print_dul_node_value(DuLinkList dl)
{unsigned i, n;if (!dl) return ;i &#61; 1;n &#61; dl->nm;for (i &#61; 1; i <&#61; n; &#43;&#43;i) {printf("%d ", dl->dt);dl &#61; dl->pn;}printf("\n");
}/* 简单测试双向链表 */
int main(void)
{unsigned dl_len;DuLinkList dla, dlb, dlc;dl_len &#61; 7;dla &#61; create_dul_link_list(dl_len);dlb &#61; create_dul_link_list(dl_len);print_dul_node_value(dla);print_dul_node_value(dlb);dlc &#61; merge_dul_link_list(dla, dlb);print_dul_node_value(dlc);//free_dul_link_list(dlc);return 0;
}

运行double_link_list.c得以下结果&#xff1a;
这里写图片描述


2.3 一元多项式的表示及相加

06.23
这里写图片描述


3 栈和队列


3.1 栈及栈的简单应用

。栈是限定仅在表尾进行插入或删除操作的线性表。表尾端称为栈顶&#xff0c;表头端称为栈底。顺序栈即利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素&#xff0c;同时设置一个指向栈顶元素的指针。[链栈的各个数据元素的存储单元不一定连续]


(1) 顺序栈

例 – 用C实现一个简单的顺序栈

06.23
一般来说&#xff0c;在初始化设空栈时不应限定栈的最大容量。一个较合理的做法是&#xff1a;先为栈分配一个基本容量&#xff0c;然后在应用过程中&#xff0c;当栈的空间不够使用时在逐段扩大。

[1] 描述栈的结构体类型

/* 描述栈的结构体类型 */
typedef SElemType int;
typedef struct _SqStack{SElemType *base;SElemType *top;int stacksize;
}SqStack;

其中&#xff0c;stacksize指示栈的当前可使用的最大容量。栈的初始化操作为&#xff1a;按设定的初始分配量进行第一次分配&#xff0c;base为栈底指针&#xff0c;在顺序栈中&#xff0c;它始终指向栈底的位置&#xff0c;若base的值为NULL&#xff0c;则表明栈结构不存在。称top为栈顶指针&#xff0c;其初值指向栈底&#xff0c;即top&#61;base可作为栈空的标记&#xff0c;每当插入新的栈顶元素时&#xff0c;指针top增1&#xff1b;删除栈顶元素时&#xff0c;指针top减1&#xff0c;因此&#xff0c;非空栈中的栈顶指针始终在栈顶元素的下一个位置上。

[2] 跟栈相关的基本操作
06.26
stack_basic.c

/* stack_basic.c* 栈的简单描述与实现* 2016.06.23 - 06.26*/
#include <stdio.h>
#include <stdlib.h>#define STACK_INIT_SIZE 100 // 栈空间初始分配大小
#define STACKINCREMENT 10 // 栈空间分配增量
#define OK 0 // 函数正常返回
#define NK 11 // 函数非正常返回
#define NP 22 // 函数参数无效/* 描述栈的结构体类型 */
typedef int SElemType;
typedef struct _SqStack{SElemType *base;SElemType *top;int stacksize;
}SqStack;/* 基本操作 */
// 构造一个空栈 - 为栈分配空间&#xff0c;指向栈顶与栈底的变量都指向栈底
int init_stack(SqStack *stack)
{if (!stack) return NP;stack->base &#61; (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));if (!stack->base) return NK;stack->top &#61; stack->base;stack->stacksize &#61; STACK_INIT_SIZE;return OK;
}// 销毁栈 - 释放为栈分配的空间
void destroy_stack(SqStack *stack)
{if (!stack) return;if (stack->base) {stack->stacksize &#61; 0;free(stack->base);stack->base &#61; NULL;stack->top &#61; NULL;}
}// 将栈设为空栈 - 将指向栈顶的变量指向栈底
void clear_stack(SqStack *stack)
{if (!stack) return;if (stack->top && stack->base)stack->top &#61; stack->base;
}// 判断是否为空栈
int is_stack_empty(SqStack *stack)
{if (stack && stack->base && stack->top)return (stack->base &#61;&#61; stack->top);elsereturn NP;
}// 获取栈的长度
int get_stack_length(SqStack *stack)
{if (stack) return stack->stacksize;else return NP;
}// 获取栈顶元素
SElemType get_top(SqStack *stack)
{SElemType *top;if (stack && stack->top && stack->base && \stack->top !&#61; stack->base) {top &#61; stack->top - 1;return *top;}return NP;
}// 往栈顶中插入一个元素
int push(SqStack *stack, SElemType e)
{int status;SElemType *base;status &#61; is_stack_empty(stack);if (NP !&#61; status) {if (stack->top - stack->base < stack->stacksize) { // 栈未满*stack->top &#61; e;stack->top&#43;&#43;;return OK;} else { // 栈已满base &#61; (SElemType *)realloc(stack->base, (stack->stacksize &#43; STACKINCREMENT) * sizeof(SElemType));if (base) return (NK);stack->base &#61; base;stack->stacksize &#43;&#61; STACKINCREMENT;*stack->top &#61; e;stack->top&#43;&#43;;return OK;}}return NP;
}// 删除栈顶元素
int pop(SqStack *stack)
{int status;status &#61; is_stack_empty(stack);if (NP !&#61; status && !status) {stack->top--;return OK;}return NK;
}
// 遍历栈
void traverse_stack(SqStack *stack)
{int status;SElemType *pe;status &#61; is_stack_empty(stack);if (NP !&#61; status && !status) {pe &#61; stack->top - 1;while (pe - stack->base) {printf("%d ", *pe--); // int}printf("%d\n", *pe);}
}/* 简单测试栈 - 部分函数 */
int main(void)
{int i, rv;SqStack stack;if ((rv &#61; init_stack(&stack)) !&#61; OK) // 初始化栈exit(NK);for (i &#61; 0; i < STACK_INIT_SIZE; &#43;&#43;i) // 入栈push(&stack, i);traverse_stack(&stack); // 遍历栈destroy_stack(&stack); // 销毁栈return 0;
}

在shell中运行该程序&#xff0c;得到以下测试结果&#xff1a;
这里写图片描述


(2) 栈的简单应用

06.27
[还相差甚远]

[1] 数制转换
这里写图片描述

[2] 括号匹配的检验
这里写图片描述

[3] 行编辑程序
这里写图片描述

[4] 迷宫求解
这里写图片描述

[5] 表达式求值
这里写图片描述


3.2 栈与递归的实现

06.28
[…如汉诺塔、八皇后问题…]


3.3 队列

队列。队列是一种先进先出的线性表。它只允许在表的一端&#xff08;队尾&#xff09;进行插入&#xff0c;而在另一端&#xff08;队头&#xff09;删除元素。
这里写图片描述


(1) 链队列

!例 – 用C语言实现一个简单的链队列程序


(2) 循环队列

这里写图片描述


3.4 离散事件模拟

[..银行业务模拟程序..]

06.09


4 串


4.1 串的基本操作

&#xff08;字符串&#xff09;。串是由零个或多个字符组成的有限序列。

串定长顺序存储表示。用一组地址连续的内存单元存储串值的字符序列。

堆分配存储表示。仍以一组地址连续的内存单元存储串值的字符序列&#xff0c;但它们的存储空间是在程序执行过程中动态分配的。

串的块链存储表示。以结点方式存储各个串。

06.30
例 – 用C语言编写一个简单的关于串&#xff08;顺序存储方式&#xff09;的程序。&#xff08;串比较、串连接、求串长度、串模式匹配等&#xff09;[串相关的操作无须涉及任何与内核交互&#xff0c;《TCPL》等书涉及关于串函数的一些编写内容&#xff0c;本书中的模式匹配算法可以值得&#xff08;因为没怎么看过&#xff09;一看]。


4.2 串的简单应用

06.29


(1) 文本编辑

这里写图片描述


(2) 建立词索引表

信息检索主要操作。在大量存放的磁盘上的信息中查询一个特定的信息&#xff08;为了提高查询效率&#xff0c;一个重要的问题就是建立一个好的索引系统&#xff09;。
这里写图片描述

[2016.06.12 - 10:15]


推荐阅读
  • C语言中全部可用的数学函数有哪些?2.longlabs(longn);求长整型数的绝对值。3.doublefabs(doublex);求实数的绝对值。4.doublefloor(d ... [详细]
  • 本文将带你快速了解 SpringMVC 框架的基本使用方法,通过实现一个简单的 Controller 并在浏览器中访问,展示 SpringMVC 的强大与简便。 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • 字符串学习时间:1.5W(“W”周,下同)知识点checkliststrlen()函数的返回值是什么类型的?字 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • 本文总结了在SQL Server数据库中编写和优化存储过程的经验和技巧,旨在帮助数据库开发人员提升存储过程的性能和可维护性。 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 如何使用 `org.opencb.opencga.core.results.VariantQueryResult.getSource()` 方法及其代码示例详解 ... [详细]
  • 如何将Python与Excel高效结合:常用操作技巧解析
    本文深入探讨了如何将Python与Excel高效结合,涵盖了一系列实用的操作技巧。文章内容详尽,步骤清晰,注重细节处理,旨在帮助读者掌握Python与Excel之间的无缝对接方法,提升数据处理效率。 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
author-avatar
丿车荣璇
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有