C语言数据结构(大话数据结构——笔记1)数据结构绪论算法线性表
Posted Dontla
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言数据结构(大话数据结构——笔记1)数据结构绪论算法线性表相关的知识,希望对你有一定的参考价值。
说是这个教程是按照《大话数据结构》这本书来编写的:数据结构与算法经典书籍——大话数据结构(带配套源码)
↑废话太TM多了,换一个!
【搞定数据结构和算法】数据结构和算法考研教程数据结构考研严蔚敏
这个好像可以,看这个。。。
但是没更完啊!换一个!
我裂开了,还是回去看那个小甲鱼的罗里吧嗦的教程吧!
越听越晕,wo TM还是不看视频了,直接看书吧,《大话数据结构》!
文章目录
- 第一章:数据结构绪论
- 第二章:算法
- 事前分析估算方法(53)
- 分析算法运行时间:将基本操作数量表示成输入规模的函数(54)
- 判断一个算法效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高阶项)(57)
- 算法时间复杂度 T(n) = O(f(n))(57)
- 大O记法 常数阶 线性阶 平方阶(58)
- 推导大O阶方法(58)
- 对数阶(60)
- 常见时间复杂度及排名(63)
- 运行时间通常指最坏的情况的运行时间(64)
- 平均运行时间:最有意义的运行时间(需要用上概率计算方法)(64)
- 算法空间复杂度:用空间换时间的方法(65)
- 算法的空间复杂度通过计算算法所需的存储空间实现,算法空间复杂度的计算公式记作:S(n) = O(f(n)),其中,n为问题的规模,f(n)为语句关于n所占存储空间的函数。(65)
- 空间复杂度:算法原地工作O(1) (65)
- 复杂度通常指时间复杂度(65)
- 大O阶的推导方法(66)
- 常见时间复杂度所耗时间排列顺序(66)
- 第三章:线性表
- 线性表:零个或多个数据元素的有限序列(71)
- 前驱元素与后继元素(71)
- 线性表的长度n,当n = 0,这个线性表称为空表(71)
- 线性表的抽象数据类型(73)
- 线性表的顺序存储结构(75)
- 数组长度与线性表长度的区别:数组长度是存放线性表的存储空间的长度,线性表长度是线性表中数据元素的个数(77)
- 随机存储结构的概念(有啥用?)(78)
- 顺序存储结构的插入与删除(固定表,没啥优势吧!为什么讲这个?)(78)
- 线性表顺序存储结构的优缺点(82)
- 线性表的链式存储结构(83)
- 数据域与指针域,结点(node)的概念(85)
- 头指针:链表第一个结点的存储位置,如果有头结点,则指向头结点,头结点不是必须的(85)
- 头结点:可存线性表长度等公共数据(86)
- 单链表的读取(88)
- 单链表的插入与删除(89)
- 单链表的优势:插入或删除数据的频繁操作(94)
- 单链表整表的创建(94)
- 头插法与尾插法(95)
- 单链表整表的删除(97)
- 单链表结构与顺序存储结构优缺点(98)
- 静态链表:用数组描述的链表(游标实现法)(这个貌似只适合在不能用指针的语言中使用,如java、c#)(99)
- 静态链表优缺点(可能静态链表平时都不怎么用得到!)(105)
- 单向循环链表(106)
- 尾指针(rear)(108)
- 循环链表的合并(108)
- 双向循环链表(109)
- 01线性表顺序存储_List(代码示例)
- 02线性表链式存储_LinkList(代码示例)
- 03静态链表_StaticLinkList(代码示例)
第一章:数据结构绪论
逻辑结构与物理结构(存储结构)
顺序存储结构与链式存储结构
原子类型数据与结构类型数据(39)
抽象数据类型(40)
第二章:算法
事前分析估算方法(53)
分析算法运行时间:将基本操作数量表示成输入规模的函数(54)
判断一个算法效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高阶项)(57)
算法时间复杂度 T(n) = O(f(n))(57)
大O记法 常数阶 线性阶 平方阶(58)
推导大O阶方法(58)
对数阶(60)
常见时间复杂度及排名(63)
运行时间通常指最坏的情况的运行时间(64)
平均运行时间:最有意义的运行时间(需要用上概率计算方法)(64)
算法空间复杂度:用空间换时间的方法(65)
算法的空间复杂度通过计算算法所需的存储空间实现,算法空间复杂度的计算公式记作:S(n) = O(f(n)),其中,n为问题的规模,f(n)为语句关于n所占存储空间的函数。(65)
空间复杂度:算法原地工作O(1) (65)
复杂度通常指时间复杂度(65)
大O阶的推导方法(66)
常见时间复杂度所耗时间排列顺序(66)
第三章:线性表
线性表:零个或多个数据元素的有限序列(71)
前驱元素与后继元素(71)
线性表的长度n,当n = 0,这个线性表称为空表(71)
线性表的抽象数据类型(73)
线性表的顺序存储结构(75)
数组长度与线性表长度的区别:数组长度是存放线性表的存储空间的长度,线性表长度是线性表中数据元素的个数(77)
随机存储结构的概念(有啥用?)(78)
顺序存储结构的插入与删除(固定表,没啥优势吧!为什么讲这个?)(78)
线性表顺序存储结构的优缺点(82)
线性表的链式存储结构(83)
数据域与指针域,结点(node)的概念(85)
头指针:链表第一个结点的存储位置,如果有头结点,则指向头结点,头结点不是必须的(85)
头结点:可存线性表长度等公共数据(86)
单链表的读取(88)
单链表的插入与删除(89)
单链表的优势:插入或删除数据的频繁操作(94)
单链表整表的创建(94)
头插法与尾插法(95)
单链表整表的删除(97)
单链表结构与顺序存储结构优缺点(98)
下面不太理解,如果用用户名去查找,顺序存储结构与链表不都需要从头查到尾一个一个去匹配吗?
静态链表:用数组描述的链表(游标实现法)(这个貌似只适合在不能用指针的语言中使用,如java、c#)(99)
(通俗易懂)(102)
静态链表优缺点(可能静态链表平时都不怎么用得到!)(105)
单向循环链表(106)
或(用尾指针代替头指针的单向循环链表)
尾指针(rear)(108)
循环链表的合并(108)
双向循环链表(109)
01线性表顺序存储_List(代码示例)
#include "stdio.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"
constexpr auto OK = 1;
constexpr auto ERROR = 0;
constexpr auto TRUE = 1;
constexpr auto FALSE = 0;
constexpr auto MAXSIZE = 20 /* 存储空间初始分配量 */;
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType; /* ElemType类型根据实际情况而定,这里假设为int */
Status visit(ElemType c)
{
printf("%d ", c);
return OK;
}
typedef struct
{
ElemType data[MAXSIZE]; /* 数组,存储数据元素 */
int length; /* 线性表当前长度 */
}SqList;
/* 初始化顺序线性表 */
Status InitList(SqList* L)
{
L->length = 0;
return OK;
}
/* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
Status ListEmpty(SqList L)
{
if (L.length == 0)
return TRUE;
else
return FALSE;
}
/* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
Status ClearList(SqList* L)
{
L->length = 0;
return OK;
}
/* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
int ListLength(SqList L)
{
return L.length;
}
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值,注意i是指位置,第1个位置的数组是从0开始 */
Status GetElem(SqList L, int i, ElemType* e)
{
if (L.length == 0 || i<1 || i>L.length)
return ERROR;
*e = L.data[i - 1];
return OK;
}
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:返回L中第1个与e满足关系的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为0 */
int LocateElem(SqList L, ElemType e)
{
int i;
if (L.length == 0)
return 0;
for (i = 0; i < L.length; i++)
{
if (L.data[i] == e)
break;
}
if (i >= L.length)
return 0;
return i + 1;
}
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(SqList* L, int i, ElemType e)
{
int k;
if (L->length == MAXSIZE) /* 顺序线性表已经满 */
return ERROR;
if (i<1 || i>L->length + 1)/* 当i比第一位置小或者比最后一位置后一位置还要大时 */
return ERROR;
if (i <= L->length) /* 若插入数据位置不在表尾 */
{
for (k = L->length - 1; k >= i - 1; k--) /* 将要插入位置之后的数据元素向后移动一位 */
L->data[k + 1] = L->data[k];
}
L->data[i - 1] = e; /* 将新元素插入 */
L->length++;
return OK;
}
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Status ListDelete(SqList* L, int i, ElemType* e)
{
int k;
if (L->length == 0) /* 线性表为空 */
return ERROR;
if (i<1 || i>L->length) /* 删除位置不正确 */
return ERROR;
*e = L->data[i - 1];
if (i < L->length) /* 如果删除不是最后位置 */
{
for (k = i; k < L->length; k++)/* 将删除位置后继元素前移 */
L->data[k - 1] = L->data[k];
}
L->length--;
return OK;
}
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
Status ListTraverse(SqList L)
{
int i;
for (i = 0; i < L.length; i++)
visit(L.data[i]);
printf("\\n");
return OK;
}
void unionL(SqList* La, SqList Lb)
{
int La_len, Lb_len, i;
ElemType e;
La_len = ListLength(*La);
Lb_len = ListLength(Lb);
for (i = 1; i <= Lb_len; i++)
{
GetElem(Lb, i, &e);
if (!LocateElem(*La, e))
ListInsert(La, ++La_len, e);
}
}
int main()
{
SqList L;
SqList Lb;
ElemType e;
Status i;
int j, k;
i = InitList(&L);
printf("初始化L后:L.length=%d\\n", L.length);
for (j = 1; j <= 5; j++)
i = ListInsert(&L, 1, j);
printf("在L的表头依次插入1~5后:L.data=");
ListTraverse(L);
printf("L.length=%d \\n", L.length);
i = ListEmpty(L);
printf("L是否空:i=%d(1:是 0:否)\\n", i);
i = ClearList(&L);
printf("清空L后:L.length=%d\\n", L.length);
i = ListEmpty(L);
printf("L是否空:i=%d(1:是 0:否)\\n", i);
for (j = 1; j <= 10; j++)
ListInsert(&L, j, j);
printf("在L的表尾依次插入1~10后:L.data=");
ListTraverse(L);
printf("L.length=%d \\n", L.length);
ListInsert(&L, 1, 0);
printf("在L的表头插入0后:L.data=");
ListTraverse(L);
printf("L.length=%d \\n", L.length);
GetElem(L, 5, &e);
printf("第5个元素的值为:%d\\n", e);
for (j = 3; j <= 4; j++)
{
k = LocateElem(L, j);
if (k)
printf("第%d个元素的值为%d\\n", k, j);
else
printf("没有值为%d的元素\\n", j);
}
k = ListLength(L); /* k为表长 */
for (j = k + 1; j >= k; j--)
{
i = ListDelete(&L, j, &e); /* 删除第j个数据 */
if (i == ERROR)
printf("删除第%d个数据失败\\n", j);
else
printf("删除第%d个的元素值为:%d\\n", j, e);
}
printf("依次输出L的元素:");
ListTraverse(L);
j = 5;
ListDelete(&L, j, &e); /* 删除第5个数据 */
printf("删除第%d个的元素值为:%d\\n", j, e);
printf("依次输出L的元素:");
ListTraverse(L);
//构造一个有10个数的Lb
i = InitList(&Lb);
for (j = 6; j <= 15; j++)
i = ListInsert(&Lb, 1, j);
unionL(&L, Lb);
printf("依次输出合并了Lb的L的元素:");
ListTraverse(L);
return 0;
}
运行结果:
初始化L后:L.length=0
在L的表头依次插入1~5后:L.data=5 4 3 2 1
L.length=5
L是否空:i=0(1:是 0:否)
清空L后:L.length=0
L是否空:i=1(1:是 0:否)
在L的表尾依次插入1~10后:L.data=1 2 3 4 5 6 7 8 9 10
L.length=10
在L的表头插入0后:L.data=0 1 2 3 4 5 6 7 8 9 10
L.length=11
第5个元素的值为:4
第4个元素的值为3
第5个元素的值为4
删除第12个数据失败
删除第11个的元素值为:10
依次输出L的元素:0 1 2 3 4 5 6 7 8 9
删除第5个的元素值为:4
依次输出L的元素:0 1 2 3 5 6 7 8 9
依次输出合并了Lb的L的元素:0 1 2 3 5 6 7 8 9 15 14 13 12 11 10
02线性表链式存储_LinkList(代码示例)
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */
Status visit(ElemType c)
{
printf("%d ", c);
return OK;
}
typedef struct Node
{
ElemType data;
struct Node* next;
}Node;
typedef struct Node* LinkList; /* 定义LinkList */
/* 初始化顺序线性表 */
Status InitList(LinkList* L)
{
*L = (LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
if (!(*L)) /* 存储分配失败 */
return ERROR;
(*L)->next = NULL; /* 指针域为空 */
return OK;
}
/* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
Status ListEmpty(LinkList L)
{
if (L->next)
return FALSE;
else
return TRUE;
}
/* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
Status ClearList(LinkList* L)
{
LinkList p, q;
p = (*L)->next; /* p指向第一个结点 */
while (p) /* 没到表尾 */
{
q = p->next;
free(p);
p = q;
}
(*L)->next = NULL; /* 头结点指针域为空 */
return OK;
}
/* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
int ListLength(LinkList L)
{
int i = 0;
LinkList p = L->next; /* p指向第一个结点 */
while (p)
{
i++;
p = p->next;
}
return i;
}
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值 */
Status 以上是关于C语言数据结构(大话数据结构——笔记1)数据结构绪论算法线性表的主要内容,如果未能解决你的问题,请参考以下文章