线性表链式存储API
来源:互联网 发布:多益网络在线笔试 编辑:程序博客网 时间:2024/04/30 07:18
链式存储定义:
为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息。
线性表链式存储优点:
无需一次性定制链表的容量
插入和删除操作无需移动数据元素
线性表链式存储缺点:
数据元素必须保存后继元素的位置信息
获取指定数据的元素操作需要顺序访问之前的元素
线性表链式存储与顺序存储的比较:
线性表的顺序存储结构要求逻辑关系上相邻的元素在物理位置上也相邻,这样方便了随机存取,但是在插入和删除元素时,需要移动大量元素;
而线性表的链式存储则不要求逻辑上相邻的元素在物理位置上也相邻,因此它没有顺序存储结构的可随机存取的优点,不过在插入和删除元素时比较方便。
linklist.h
#ifndef __MYLINKLIST_H__#define __MYLINKLIST_H__//传统链表 数据和指针在一个节点//现代链表 把指针独立出来,做成节点 在包含数据的节点中包含这个独立节点typedef void LinkList;typedef struct _tag_LinkListNode//被大千世界包含{ struct _tag_LinkListNode*next;}LinkListNode;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 <stdlib.h>#include <string.h>#include "linklist.h"//头结点 封装了一个 节点和链表长度typedef struct _tag_LinkList{ LinkListNode header; int length;}TLinkList;LinkList* LinkList_Create()//创建{ TLinkList *ret = NULL; ret = (TLinkList *)malloc(sizeof(TLinkList)) ; memset(ret,0,sizeof(TLinkList));//等价于下面两句 //tmp->length = 0; //tmp->header.next = NULL; return ret;//任何类型的指针都可以直接赋值给void*}void LinkList_Destroy(LinkList* list){ if (list!=NULL) { free(list); list = NULL; }}//让链表恢复到初始化状态void LinkList_Clear(LinkList* list){ TLinkList *tlist = NULL; if (list==NULL) { return ; } tlist = (TLinkList *)list;//void*类型的指针必须转换后赋值给其他类型的指针 tlist->length = 0; tlist->header.next = NULL;}int LinkList_Length(LinkList* list){ TLinkList *tlist = NULL; if (list==NULL) { return 0; } tlist = (TLinkList *)list;//void*类型的指针先转换再赋值给相应类型的指针 return tlist->length;}int LinkList_Insert(LinkList*list,LinkListNode*node,int pos){ int ret = 0,i; LinkListNode*current=NULL;//引入辅助指针变量? TLinkList *tList = NULL; if (list ==NULL||node==NULL||pos<0) { ret = -1; printf("func LinkList_Insert() error :%d\n ",ret); return ret; } tList = (TLinkList*)list;//void类型的指针需要转换后赋值给相应的指针类型数据 current = &tList->header;//一开始让辅助指针current指向链表头结点的LinkListNode //假设要删除3号位置的元素(从0号位置开始),3号元素位置保存在2号位置元素的next域 //移动辅助指针变量current指向2号位置 for (i=0;i<pos&&(current->next!=NULL);i++) { current = current->next; } //让新节点node指向后续节点 node->next = current->next; //当前位置2号 的next域赋值为node current->next = node; tList->length++; return ret;}LinkListNode* LinkList_Get(LinkList*list,int pos){ int ret = 0,i; LinkListNode*current=NULL; TLinkList *tList = NULL; if (list ==NULL||pos<0) { ret = -1; printf("func LinkList_Get() error :%d\n ",ret); return NULL; } tList = (TLinkList*)list; current = &tList->header;//辅助指针变量指向链表头部 for (i=0;i<pos&&(current->next!=NULL);i++) { current = current->next; } return current->next;}LinkListNode* LinkList_Delete(LinkList*list,int pos){ int i; LinkListNode*current=NULL;//引入辅助指针变量 LinkListNode*ret=NULL;//引入辅助指针变量 缓存删除的节点 返回 TLinkList *tList = NULL; if (list ==NULL||pos<0) { printf("func LinkList_Delete() error\n"); return NULL; } tList = (TLinkList*)list; current = &tList->header;//一开始让辅助指针current指向链表头结点的LinkListNode //假设删除3号位置节点 移动current指向2号位置 for (i=0;i<pos&&(current->next!=NULL);i++) { current = current->next; } ret = current->next;//缓存即将删除的节点(3号位置) //连线 current->next = ret->next; tList->length--; return ret;}
test.c
#define _CRT_SECURE_NO_WARNINGS#include <stdlib.h>#include<stdio.h>#include <string.h>#include "linklist.h"//现代链表:业务节点(大千世界)包含链表节点(我)typedef struct Teacher { LinkListNode listnode; char*name; int age;}Teacher;int main(){ //创建一个线性表 LinkList* list= NULL; int length ,ret,i; Teacher t1,t2,t3,t4,t5,t6; t1.age = 30; t2.age = 32; t3.age = 33; t4.age = 34; t5.age = 35; t6.age = 36; //创建并返回TLinkList类型的头结点 list = LinkList_Create();//任意类型的指针变量都可以直接辅助给void* if (list == NULL) { return -1; } length = LinkList_Length(list);//TLinkList printf("length:%d\n",length); //插入 /*说明LinkListNode*)&t1 把结构体Teacher转为结构体LinkListNode 是可以的 因为结构体Teacher的地址和结构体Teacherz中LinkListNode地址重叠*/ //实现链表算法和具体业务节点的分离(细细体会) //头插法 /*ret = LinkList_Insert(list,(LinkListNode*)&t1, 0); ret = LinkList_Insert(list,(LinkListNode*)&t3, 0); ret = LinkList_Insert(list,(LinkListNode*)&t4, 0); ret = LinkList_Insert(list,(LinkListNode*)&t5, 0); ret = LinkList_Insert(list,(LinkListNode*)&t6, 0);*/ //尾插法 ret = LinkList_Insert(list,(LinkListNode*)&t1, LinkList_Length(list)); ret = LinkList_Insert(list,(LinkListNode*)&t3, LinkList_Length(list)); ret = LinkList_Insert(list,(LinkListNode*)&t4, LinkList_Length(list)); ret = LinkList_Insert(list,(LinkListNode*)&t5, LinkList_Length(list)); ret = LinkList_Insert(list,(LinkListNode*)&t6, LinkList_Length(list)); length = LinkList_Length(list); printf("length:%d\n",length); //遍历 for (i=0;i<length;i++) { Teacher *tmp =(Teacher *)LinkList_Get(list,i); if (tmp==NULL) { return; } printf("%d\n",tmp->age); } //删除 while (LinkList_Length(list)>0) { Teacher*tmp =(Teacher*) LinkList_Delete(list,0); if (tmp==NULL) { return ; } printf("delete : %d\n",tmp->age); } //销毁 //LinkList_Destroy(list); system("pause"); return 0;}
0 0
- 线性表链式存储API
- 线性表链式存储
- 线性表链式存储
- 线性表链式存储
- 线性表链式存储
- 线性表链式存储
- 线性表链式存储
- 线性表链式存储
- 线性表链式存储设计与实现 - API实现
- 线性表链式存储结构
- 线性表链式存储结构
- 线性表链式存储习题
- 线性表链式存储实现
- 线性表链式存储结构
- 线性表链式存储结构
- 线性表链式存储的实现
- 数据结构之线性表链式存储
- 【数据结构】线性表链式存储_LinkList
- 学习封装 MVC (3)
- 多级指针运算
- 进程的有哪几种状态,状态转换图,及导致转换的事件
- HDU 4607 Park Visit 树的直径
- 替换空格
- 线性表链式存储API
- C++ 求排列函数 next_permutation, prev_permutation
- Intellij快捷键
- 指定Action,Category调用系统Activity
- CUDA Toolkit 各版本文档
- 动态显示当前系统时间和移除定时器
- C#静态字段和静态方法
- 指针练习 1002 将数组a中的n个整数按相反顺序存放
- 学习笔记(十二)—设计模式(续)