线性表的链式存储

来源:互联网 发布: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
原创粉丝点击