线性表的链式存储
来源:互联网 发布:mac dock栏透明 编辑:程序博客网 时间:2024/04/30 02:48
1.链式存储定义:为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息。
2.链式存储逻辑结构:
n个节点链接成一个链式线性表的结构叫做链表,当每个节点只包含一个指针域是叫做单链表。
3.链表的基本概念:
表头结点: 链表中的第一个结点 ,包含指向第一个数据元素的指针以及链表自身的一些信息。
数据结点: 链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息。
尾结点: 链表中最后一个数据结点,其 后继。
在C语言中可以用结构体来定义链表中的指针域.
链表中的表头节点也可以用结构体来实现
typedef struct _tag_Link_listNode_ Link_list_node
struct _tag_Link_listNode_
{
Link_list_node* next;
};
结点指针域定义
typedef struct _tag_Linklist
{
Link_list_node hearder;
int length;
}TlinkList;
头结点定义
struct Value
{
_Link_list_node header;
int v;
}
数据元素定义实例
4.获取第POS个元素的算法操作:
1.判断线性表是否合法
2.判断位置是否合法
3.由表头开始通过next指针移动POS之后,当前元素的next指针即指向要获取的元素。
LinkListNode* current = (LinkListNode*)list;
for(int i =0;i<pos;i++)
{
current=current->next;
}
ret=*current->next;
5.插入元素到pos的算法操作:(在新的链表形成之前,旧的链表不能断裂)
1.判断线性表是否合法
2.判断位置是否合法
3.有表头开始通过next指针移动pos次之后,当前元素的next指针即指向要插入的位置
4. 将新元素插入
5.线性表的长度加1
LinkListNode* current=(LinkListNode*)list
for(int i=0;(i<pos)&&(current<-next!=NULL);i++)
{
current=current->next;
}
node->next=current->next;
corrent->next=node;
sList++;
6.删除第POS个元素的算法操作:
1.判断线性表是否合法
2.判断插入位置是否合法
3.获取第POS个元素
4.将第POS个元素删除
5.线性表长度减1
TLinkList* sList=(TLinkList*)list;
LinklistNode* ret = NUll;
int i=0;
if((sList !=NULL)&&(0<pos)&&(pos<sList->length))
{
LinklistNode* current=(LinkListNode*)list; //current指向表头
for(int i=0;i<pos;i++)
{
current = current->next;
}
ret=current->next;
current->next=ret->next;
Slist->length--;
}
可以复用的链表实例
.h文件
#ifndef _LINKLIST_H_
#define _LINKLIST_H_
typedef void LinkList; //为了实现数据的封装,void*作为右值赋值给其他指针是,需要进程强制类型转换
typedef struct _tag_LinkListNode LinkListNode;
/*包含指针域的结构体*/
struct _tag_LinkListNode
{
LinkListNode* next; //指针域
};
LinkList* LinkList_Creat();
void LinkList_Destory(LinkList* list);
void LinkList_Clear(LinkList* list);
int LinkList_Capacity(LinkList* List);
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos);
LinkListNode* LinkList_Delete(LinkList* list, int pos);
LinkListNode* LinkList_Get(LinkList* list, int pos);
int SeqList_Length(LinkList* list);
#endif
.c文件
#include<stdio.h>
#include<malloc.h>
#include"Linklist.h"
/*单链表的头结点*/
typedef struct _tag_LinkList
{
LinkListNode header; //指向下一个数据元素的指针
int length; //指示整个链表的长度
}TLinkList;
LinkList* LinkList_Creat() //O(1)
{
TLinkList *ret = (TLinkList*)malloc(sizeof(TLinkList)); //申请一个表头结点
if (ret != NULL)
{
ret->length = 0;
ret->header.next = NULL;
}
return ret;
}
/*销毁已经创建的单链表,即释放申请的内存*/
void LinkList_Destory(LinkList* list)
{
free(list);
}
/*清空链表,即将list的长度变为0*/
void LinkList_Clear(LinkList* list)
{
TLinkList* slist = (LinkList*)list; //为了使用头结点里的信息进行强制类型转换
//void*作为右值赋值给其他指针是,需要进程强制类型转换
if (slist != NULL)
{
slist->length = 0;
slist->header.next = NULL;
}
}
/*得到单链表的长度*/ //o)
int SeqList_Length(LinkList* list)
{
int ret = -1;
TLinkList* slist = (TLinkList*)list;
if (slist != NULL)
{
ret=slist->length;
}
return ret;
}
/*向链表中插入一个元素*/
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)
{
TLinkList* slist = (TLinkList*)list;
int i = 0;
int ret = 1;
ret = (slist != NULL) && (pos >= 0) && (node != NULL);
if (ret)
{
LinkListNode* current = (LinkListNode*)slist;//定义一个current指针使其指向头结点
for (i = 0; (i < pos) && (current->next != NULL); i++)
{
current = current->next;
}
current->next = node->next;
current->next = node;
slist->length++;
}
return ret;
}
/*从链表中得到一个元素*/
LinkListNode* LinkList_Get(LinkList* list, int pos)
{
TLinkList* slist = (TLinkList*)list;
LinkListNode* ret=NULL;
int i = 0;
if ((pos >= 0) && (slist != NULL) && (pos <= slist->length))
{
LinkListNode* current = (LinkListNode*)list;
for (i = 0; i < pos; i++)
{
current = current->next;
}
ret = current->next;
}
return ret;
}
/*删除链表中的一个元素*/
LinkListNode* LinkList_Delete(LinkList* list, int pos)
{
TLinkList* slist = (TLinkList*)list;
LinkListNode* ret = NULL;
int i = 0;
if ((pos >= 0) && (slist != NULL) && (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"Linklist.h"
struct Value
{
LinkListNode header;
int v;
};
int main()
{
LinkList* list = LinkList_Creat();
int i = 0;
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, SeqList_Length(list));
LinkList_Insert(list,(LinkListNode*)&v2, SeqList_Length(list));
LinkList_Insert(list,(LinkListNode*)&v3, SeqList_Length(list));
LinkList_Insert(list,(LinkListNode*)&v4, SeqList_Length(list));
LinkList_Insert(list,(LinkListNode*)&v5,SeqList_Length(list));
for (i = 0; i < SeqList_Length(list); i++)
{
struct Value* pv = (struct Value*)LinkList_Get(list,i);
printf("%d\n", pv->v);
}
printf("list length is %d\n", SeqList_Length(list));
while (SeqList_Length(list) > 0)
{
struct Value* pv = (struct Value*)LinkList_Delete(list, SeqList_Length(list) - 1);
printf("%d\n",pv->v);
}
printf("list length is %d\n", SeqList_Length(list));
LinkList_Destory(list);
return 0;
}
线性表的链式存储结构的优缺点:
优点:
1.无需一次性定制链表的长度
2.插入或者删除元素操作时无需移动数据元素
缺点:
1.数据元素必须保后继元素的位置信息
2.获取指定数据的元素时需要顺序的访问该元素之前的元素
0 0
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 《线性表的链式存储》
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 表示数值的字符串
- 英语单词最全的前后缀讲解
- hdu 2159(二维完全背包)
- JAVA中this用法总结
- webkit内核简介
- 线性表的链式存储
- HTTP请求方法
- 数据库的灵活操作
- 浅析android sqlite db-journal文件
- php实习的tips(mysql_fetch_assoc返回值问题)
- 鼠标事件
- 静态链表
- 【蓝桥杯】【基础练习07】【特殊的数字】
- Java基础---------2016.4.10(2)