二。线性表
1. 掌握线性表的两种存储结构(顺序存储、链式存储)。
顺序映像
随机存取结构 O(1)
顺序存取结构 O(n) 顺序表 C语言定义和表述 静态分配(数组 长度 sqList linkList)动态分配 (基址)
顺序表 操作(线性表的基本操作在顺序表中实现)
初始化
查找(按值查找)
插入 (1.元素后移从后往前 2.插入 3.表长+1)合法性判断 移动次数
删除(前移) 移动次数
单链表(指针) 元素+指针(存放后继元素的位置)构成 链表
是由头指针唯一确定的
第一个节点之前 增加一个头结点(指针域:存放第一个元素的位置)
节点 C语言描述 linkList L
getElement() 按序号取元素
插入 只需要修改指针(i-1) 找(O(n)) 插(O(1)) 右侧地址 左侧指针 前插用后插来实现
删除 找到i-1元素(查找)
清空单链表 结构体还在 不断删除第一个节点 O(n)
构造单链表 逐个插入的过程
头插 逆序 建立一个带头结点的空的单链表 O(n)
尾插 正序 带头结点 不带头结点
2. 熟练掌握顺序表和单链表的插入、 删除等操作的实现及移动次数计算,
1. 顺序表操作
//定义表 typedef int ElemType;//定义表元素的类型 #define MAX_SIZE 100 //定义最大空间 typedef struct { ElemType *elem;//存储空间的基址 int Length;//长度 }SqList; //初始化顺序表 void InitList_sq(SqList *L) { L->Length = 0; } //查找 int ListSearch(SqList *L, ElemType e) { int i; if (L->Length < 1) { return 0; } for (size_t i = 0; i < L->Length; i++) { if (L->elem[i] == e) { return 1; } } } //插入 int ListInsert(SqList *L, int i, ElemType e) { int j; //如果插入位置不存在 if (i < 0 || i > L->Length) { return 0; } //空间已满 else if (L->Length >= MAX_SIZE) { return 0; } else { //位置后移 for (j = L->Length; j > i - 1; j--) { L->elem[j] = L->elem[j - 1]; } L->elem[i - 1] = e; L->Length++; return 1; } } //删除 int ListDelete(SqList *L, int i) { int j; //如果插入位置不存在 if (i < 0 || i > L->Length) { return 0; } //空间已空 else if (L->Length <= 0) { return 0; } else { for (j = i; j < L->Length - 1;j++) { L->elem[j - 1] = L->elem[j]; } L->Length--; return 1; } }
大佬链接(侵删):
https://blog.csdn.net/liubo_01/article/details/80186552
http://www.cnblogs.com/zhangtingkuo/p/3382281.html
https://blog.csdn.net/lishuzhai/article/details/50961396
2. 单链表操作 元素+指针(存放后继元素的位置)构成
1. 定义:单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。
2. 构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
3. 操作
typedef int ElemType;//定义表元素的类型 typedef struct LNode { ElemType data; struct LNode *next;//指向后继节点 }LinkList; //初始化单链表 void InitList(LinkList *&L) { L = (LinkList *)malloc(sizeof(LinkList));//创建头结点 L->next = NULL; } //头插法(逆序) void CreatListF(LinkList *&L, ElemType a[], int n) { int i; LinkList *s; L = (LinkList *)malloc(sizeof(LinkList));//创建头结点 L->next = NULL; for (i = 0; i < n; i++) { s = (LinkList *)malloc(sizeof(LinkList));//创建新结点 s->data = a[i];//赋值 s->next = L->next;//将*s插入在原开始节点之前,头结点之后 L->next = s; } } //尾插法(正序) void CreateLinkR(LinkList *&L, ElemType a[], int n) { int i; LinkList *s, *r; L = (LinkList *)malloc(sizeof(LinkList)); L->next = NULL; r = L;//r始终指向最后结点,开始是指向的是头结点 for (i = 0; i < n; i++) { s = (LinkList *)malloc(sizeof(LinkList)); s->data = a[i]; r->next = s;//将*s插入*r之后 r = s; } r->next = NULL;//最后一个结点指向为空 } //按序号查找元素 int GetElement(LinkList *L, int i, ElemType &e) { int j = 0; LinkList *p = L; while (j < i && p != NULL)//查找i的结点 { j++; p = p->next; } if (p == NULL)//不存在 { return 0; } else { e = p->data; return 1; } } //插入 int InsertList(LinkList *&L, int i, ElemType &e) { int j = 0; LinkList *p = L, *s; while (j < i - 1 && p != NULL)//查找i-1的结点 { j++; p = p->next; } if (p == NULL) { return 0; } else//找到位置序号为i-1的结点*p { s = (LinkList *)malloc(sizeof(LinkList)); s->data = e; s->next = p->next; p->next = s;//将*s插入到*p之后 return 1; } } //删除 int DeleteList(LinkList *&L, int i, ElemType &e) { int j = 0; LinkList *p = L, *s; while (j < i - 1 && p != NULL) { j++; p = p->next; } if (p == NULL) { return 0; } else { s = p->next;//s指向要删除的结点 if (s == NULL) { return 0;//不存在第i个结点 } else { p->next = s->next; free(s); return 1; } } } //销毁 void DestroyList(LinkList *&L) { LinkList *p = L, *q = p->next; while (q != NULL) { free(p); p = q; q = p->next; } free(p); //此时q为NULL,p指向尾结点,释放它 }
大佬链接(侵删):
https://www.cnblogs.com/vs2016/p/5960622.html
https://blog.csdn.net/fanyun_01/article/details/79831877
https://www.cnblogs.com/leaver/p/6718421.html
https://www.cnblogs.com/longl/p/6414433.html
https://blog.csdn.net/gongdileidechouzhu/article/details/57083701
3. 以及双向链表、循环链表、双向循环链表各种操作的实现。
1. 双向链表:也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。
操作:
大佬链接(侵删):
https://www.cnblogs.com/hughdong/p/6785391.html
https://blog.csdn.net/zouleideboke/article/details/76222437
http://blog.51cto.com/9291927/2063376
https://www.jianshu.com/p/78c051c9e308
https://www.cnblogs.com/corvoh/p/5595130.html
2. 循环链表:表中最后一个结点的指针域指向头结点,整个链表形成一个环。
操作:
大佬链接(侵删):
http://blog.51cto.com/9291927/2063347
https://blog.csdn.net/sinat_39061823/article/details/74935755
https://blog.csdn.net/qq_29542611/article/details/79029540
https://www.cnblogs.com/biyongyao/p/5506819.html
https://blog.csdn.net/baweiyaoji/article/details/76071053
https://blog.csdn.net/lixin_com/article/details/77964199
3. 双向循环链表:双向链表中的每一个节点有两个指针,一个指针用来指向上一个节点(前驱),另一个指针用指向下一个节点(后继)。
操作:
大佬链接(侵删):
https://www.cnblogs.com/clover-toeic/p/3793131.html
https://www.cnblogs.com/hughdong/p/6785655.html
http://blog.51cto.com/12810168/2176875?source=dra
https://blog.csdn.net/hansionz/article/details/82958918
https://www.cnblogs.com/rongweijun/p/8072677.html
4. 能运用顺序存储和链式存储结构解决实际问题。