第八课,线性表的链式存储结构
来源:互联网 发布:js返回顶部 编辑:程序博客网 时间:2024/06/08 12:39
专题二:初探门径。包括以下章节:
- 线性表的本质
- 线性表的相关操作
- 线性表的顺序存储结构
- 线性表的链式存储结构
思考
顺序表的最大问题是插入和删除需要移动大量的元素!
链式存储结构
- 链式存储定义
- 为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息。
- 为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息。
- 链式存储逻辑结构
- n个结点链接成一个链式线性表的结构叫做链表,当每个结点中只包含一个指针域时,叫做单链表。
- n个结点链接成一个链式线性表的结构叫做链表,当每个结点中只包含一个指针域时,叫做单链表。
链表的基本概念
- 表头结点
- 链表中的第一个结点,包含指向第一个数据元素的指针以及链表自身的一些信息
- 数据结点
- 链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息
- 尾结点
- 链表中的最后一个数据结点,其下一元素指针为空,表示无后继
链式存储结构
1. 在C语言中可以用结构体来定义链表中的指针域
2. 链表中的表头结点也可以用结构体实现
结点指针域定义
typedef struct _tag_LinkListNode LinkListNode;struct _tag_LinkListNode{ ListListNode* next;}
头结点定义
typedef struct _tag_LinkList{ LinkListNode header; int length;}TListList;
数据元素定义
struct Value{ LinkListNode header; int v;}
3. 获取第pos个元素操作
- 判断线性表是否合法
- 判断位置是否合法
- 由表头开始通过next指针移动pos次后,当前元素的next指针即指向要获取的元素
LinkListNode* current = (LinkListNode*)list;for(i=0;i<pos;i++){ current = current->next;}ret = current->next;
4. 插入元素操作
- 判断线性表是否合法
- 判断插入位置是否合法
- 由表头开始通过next指针移动pos次后,当前元素的next指针即指向要插入的位置
- 将新元素插入
- 线性表长度加1
LinkListNode* current = (LinkListNode*)list;for(i=0;(i<pos)&&(current->next!=NULL);i++){ current = current->next;}node->next = current->next;current->next = node;sList->length++;
5. 删除元素操作
- 判断线性表是否合法
- 判断删除位置是否合法
- 获取第pos个元素
- 将第pos个元素从链表中删除
- 线性表长度减1
TLinkList* sList = (TLinkList*)list;LinkListNode* ret = NULL;int i = 0;if((sList!=NULL) && (0<=pos) && (pos<sList->length)){ LinkListNode* current = (LinkListNode*)list; for(i=0;i<pos;i++) { current = current->next; } ret = current->next; current->next = ret->next; sList->length--;}
小结
- 优点:
- 无需一次性定制链表的容量
- 插入和删除操作无需移动数据元素
- 缺点:
- 数据元素必须保存后继元素的位置信息
- 获取指定数据的元素操作需要顺序访问之前的元素
创建可复用单链表
LinkList.h
#ifndef _LINKLIST_H_#define _LINKLIST_H_typedef void LinkList;typedef struct _tag_LinkListNode LinkListNode;struct _tag_LinkListNode{ LinkListNode* next;};LinkList* LinkList_Create();void LinkList_Destroy(LinkList* list);void LinkList_Clear(LinkList* list);int LinkList_Length(LinkList* list);int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);LinkListNode* LinkList_Get(LinkList* list, int pos);LinkListNode* LinkList_Delete(LinkList* list, int pos);#endif
LinkList.c
#include <stdio.h>#include <malloc.h>#include "LinkList.h"typedef struct _tag_LinkList{ LinkListNode header; int length;} TLinkList;LinkList* LinkList_Create() // O(1){ TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList)); if( ret != NULL ) { ret->length = 0; ret->header.next = NULL; } return ret;}void LinkList_Destroy(LinkList* list) // O(1){ free(list);}void LinkList_Clear(LinkList* list) // O(1){ TLinkList* sList = (TLinkList*)list; if( sList != NULL ) { sList->length = 0; sList->header.next = NULL; }}int LinkList_Length(LinkList* list) // O(1){ TLinkList* sList = (TLinkList*)list; int ret = -1; if( sList != NULL ) { ret = sList->length; } return ret;}int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) // O(n){ TLinkList* sList = (TLinkList*)list; int ret = (sList != NULL) && (pos >= 0) && (node != NULL); int i = 0; if( ret ) { LinkListNode* current = (LinkListNode*)sList; for(i=0; (i<pos) && (current->next != NULL); i++) { current = current->next; } node->next = current->next; current->next = node; sList->length++; } return ret;}LinkListNode* LinkList_Get(LinkList* list, int pos) // O(n){ TLinkList* sList = (TLinkList*)list; LinkListNode* ret = NULL; int i = 0; if( (sList != NULL) && (0 <= pos) && (pos < sList->length) ) { LinkListNode* current = (LinkListNode*)sList; for(i=0; i<pos; i++) { current = current->next; } ret = current->next; } return ret;}LinkListNode* LinkList_Delete(LinkList* list, int pos) // O(n){ TLinkList* sList = (TLinkList*)list; LinkListNode* ret = NULL; int i = 0; if( (sList != NULL) && (0 <= pos) && (pos < sList->length) ) { LinkListNode* current = (LinkListNode*)sList; for(i=0; i<pos; i++) { current = current->next; } ret = current->next; current->next = ret->next; sList->length--; } return ret;}
main.c
#include <stdio.h>#include <stdlib.h>#include "LinkList.h"/* run this program using the console pauser or add your own getch, system("pause") or input loop */struct Value{ LinkListNode header; int v;};int main(int argc, char *argv[]) { int i = 0; LinkList* list = LinkList_Create(); struct Value v1; struct Value v2; struct Value v3; struct Value v4; struct Value v5; v1.v = 1; v2.v = 2; v3.v = 3; v4.v = 4; v5.v = 5; LinkList_Insert(list, (LinkListNode*)&v1, LinkList_Length(list)); LinkList_Insert(list, (LinkListNode*)&v2, LinkList_Length(list)); LinkList_Insert(list, (LinkListNode*)&v3, LinkList_Length(list)); LinkList_Insert(list, (LinkListNode*)&v4, LinkList_Length(list)); LinkList_Insert(list, (LinkListNode*)&v5, LinkList_Length(list)); for(i=0; i<LinkList_Length(list); i++) { struct Value* pv = (struct Value*)LinkList_Get(list, i); printf("%d\n", pv->v); } while( LinkList_Length(list) > 0 ) { struct Value* pv = (struct Value*)LinkList_Delete(list, 0); printf("%d\n", pv->v); } LinkList_Destroy(list); return 0;}
阅读全文
0 0
- 第八课,线性表的链式存储结构
- 线性表的链式存储结构
- 链式存储结构的线性表
- 线性表的链式存储结构
- 【数据结构】线性表的链式存储结构
- 线性表的链式存储结构
- 线性表的链式存储结构
- 线性表的链式存储结构
- 线性表的链式存储结构
- 线性表的链式存储结构
- 【二】线性表的链式存储结构
- 线性表的链式存储结构
- 线性表的链式存储结构(三)
- 【数据结构】-线性表的链式存储结构
- 线性表的链式存储结构
- 线性表的链式存储结构
- 线性表的链式存储结构
- 线性表的链式存储结构
- 新浪免费天气Api简单使用说明
- 基于J2EE的管理信息系统之简单jsp实现增删改查(一)
- jsp状态
- Ubuntu 16.04 compile JDK source code
- 【linux 常用命令】linux命令大全
- 第八课,线性表的链式存储结构
- [LeetCode 611] Valid Triangle Number
- Java学习笔记-《Java程序员面试宝典》-第四章基础知识-4.7输入输出流(4.7.1-4.7.3)
- 51 nod 1188 最大公约数之和 V2(狄利克雷卷积+线性筛法)
- java学习 jstl中if标签的使用
- mybatis一级缓存问题导致第二次查询结果出现变化
- 如何根据某个实体属性字段的不同值来设置另一个实体属性字段的值
- js:制作一个简易的计数器:根据输入的两个整数和运算符,进行计算,然后输出计算结果
- 深入理解Javascript的继承和原型链