数据结构(14)单链表
2015-08-10 19:45
435 查看
用一组地址任意的存储单元存放线性表中的数据元素,以元素(数据元素的映象) + 指针(指示后继元素存储位置)= 结点(表示数据元素 或 数据元素的映象),以“结点的序列”表示线性表称作线性链表(单链表)。
有几个基本概念需要掌握,如下:
1.表头结点
链表中的第一个结点,包含指向第一个数据元素的指针以及链表自身的一些信息。
2.数据结点
链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息
3.尾结点
链表中的最后一个数据结点,其下一元素指针为空,表示无后继
这里主要介绍线性表的常用操作:
l 创建线性表
l 销毁线性表
l 清空线性表
l 将表中元素倒置
l 表元素插入
l 表元素删除
l 获取表中某个位置的元素
l 获取表长度
代码总分为三个文件:
LinkList.h : 放置功能函数的声明,以及表的声明,表结点的定义
LinkList.c : 放置功能函数的定义,以及表的定义
Main.c : 主函数,使用功能函数完成各种需求,不过一般用作测试
这里着重说下插入操作﹑删除操作和倒置操作:
插入操作:
如图
插入元素方法:
首先判断线性表﹑插入位置是否合法
由表头开始通过next指针移动pos次后,当前元素的next指针即指向要插入的位置
把当前元素(current)的next指针包含的地址赋给新元素(node)的next指针
把新元素(node)的地址赋给当前元素(current)的next指针
最后把线性表长度加1
删除操作:
如图
删除元素方法:
首先判断线性表﹑删除位置是否合法
获取第pos个元素
将第pos个元素的next指针保存的地址赋给第pos个元素前一个元素的next指针
最后把表长度减1
倒置操作:
如图
倒置元素方法:
把头结点指向的首元素的next指针赋为NULL
然后把首元素以后的结点依次每个插入到头结点和首元素中间
OK! 上代码:
LinkList.h
[cpp] view
plaincopy
#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);
void LinkList_Reverse(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
[cpp] view
plaincopy
#include <stdio.h>
#include <malloc.h>
#include "LinkList.h"
typedef struct _tag_LinkList
{
LinkListNode header;
int length;
}TLinkList;
LinkList* LinkList_Create()
{
TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));
if(ret != NULL)
{
ret->length = 0;
ret->header.next = NULL;
}
return ret;
}
void LinkList_Destroy(LinkList* list)
{
free(list);
}
void LinkList_Clear(LinkList* list)
{
TLinkList* sList = (TLinkList*)list;
if(sList!=NULL)
{
sList->header.next = NULL;
sList->length = 0;
}
}
void LinkList_Reverse(LinkList* list)
{
TLinkList* sList = (TLinkList*)list;
if((sList!=NULL)&&(sList->length>1))
{
LinkListNode* current = (LinkListNode*)sList;
LinkListNode* p = current->next;
LinkListNode* q = current->next;
q = q->next;
p->next = NULL;
p = q;
(p != NULL)
{
q = q->next;
p->next = current->next;
current->next = p;
p = q;
}
}
}
int LinkList_Length(LinkList* list)
{
TLinkList* sList = (TLinkList*)list;
int ret = -1;
if(sList!=NULL)
{
ret = sList->length;
}
return ret;
}
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)
{
TLinkList* sList = (TLinkList*)list;
int ret = (sList!=NULL) && (pos>=0) && (node!=NULL);
int i = 0;
if(ret)
{
if(pos >= sList->length)
{
pos = sList->length;
}
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)
{
TLinkList* sList = (TLinkList*)list;
LinkListNode* ret =NULL;
int i = 0;
if((sList!=NULL)&&(pos>=0) && (pos<sList->length))
{
LinkListNode* current = (LinkListNode*)sList;
for(i=0; (i<pos)&&(current->next!=NULL); 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((sList!=NULL)&&(pos>=0)&&(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
[cpp] view
plaincopy
#include <stdio.h>
#include <stdlib.h>
#include "LinkList.h"
typedef struct _tag_Value
{
LinkListNode header;
int v;
}Value;
int main(void)
{
LinkList* list = LinkList_Create();
int i = 0;
Value v1, v2, v3, v4, v5;
v1.v=1, v2.v=2, v3.v=3, v4.v=4, v5.v=5;
LinkList_Insert(list, (LinkListNode*)&v1, 0);
LinkList_Insert(list, (LinkListNode*)&v2, 0);
LinkList_Insert(list, (LinkListNode*)&v3, 0);
LinkList_Insert(list, (LinkListNode*)&v4, 0);
LinkList_Insert(list, (LinkListNode*)&v5, 0);
Value* pV = NULL;
for(i=0; i<LinkList_Length(list); i++)
{
pV = (Value*)LinkList_Get(list, i);
printf("%d\n", pV->v);
}
while(LinkList_Length(list) > 0)
{
pV = (Value*)LinkList_Delete(list, LinkList_Length(list)-1);
printf("%d\n", pV->v);
}
LinkList_Destroy(list);
return 0;
}
有几个基本概念需要掌握,如下:
1.表头结点
链表中的第一个结点,包含指向第一个数据元素的指针以及链表自身的一些信息。
2.数据结点
链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息
3.尾结点
链表中的最后一个数据结点,其下一元素指针为空,表示无后继
这里主要介绍线性表的常用操作:
l 创建线性表
l 销毁线性表
l 清空线性表
l 将表中元素倒置
l 表元素插入
l 表元素删除
l 获取表中某个位置的元素
l 获取表长度
代码总分为三个文件:
LinkList.h : 放置功能函数的声明,以及表的声明,表结点的定义
LinkList.c : 放置功能函数的定义,以及表的定义
Main.c : 主函数,使用功能函数完成各种需求,不过一般用作测试
这里着重说下插入操作﹑删除操作和倒置操作:
插入操作:
如图
插入元素方法:
首先判断线性表﹑插入位置是否合法
由表头开始通过next指针移动pos次后,当前元素的next指针即指向要插入的位置
把当前元素(current)的next指针包含的地址赋给新元素(node)的next指针
把新元素(node)的地址赋给当前元素(current)的next指针
最后把线性表长度加1
删除操作:
如图
删除元素方法:
首先判断线性表﹑删除位置是否合法
获取第pos个元素
将第pos个元素的next指针保存的地址赋给第pos个元素前一个元素的next指针
最后把表长度减1
倒置操作:
如图
倒置元素方法:
把头结点指向的首元素的next指针赋为NULL
然后把首元素以后的结点依次每个插入到头结点和首元素中间
OK! 上代码:
LinkList.h
[cpp] view
plaincopy
#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);
void LinkList_Reverse(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
[cpp] view
plaincopy
#include <stdio.h>
#include <malloc.h>
#include "LinkList.h"
typedef struct _tag_LinkList
{
LinkListNode header;
int length;
}TLinkList;
LinkList* LinkList_Create()
{
TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));
if(ret != NULL)
{
ret->length = 0;
ret->header.next = NULL;
}
return ret;
}
void LinkList_Destroy(LinkList* list)
{
free(list);
}
void LinkList_Clear(LinkList* list)
{
TLinkList* sList = (TLinkList*)list;
if(sList!=NULL)
{
sList->header.next = NULL;
sList->length = 0;
}
}
void LinkList_Reverse(LinkList* list)
{
TLinkList* sList = (TLinkList*)list;
if((sList!=NULL)&&(sList->length>1))
{
LinkListNode* current = (LinkListNode*)sList;
LinkListNode* p = current->next;
LinkListNode* q = current->next;
q = q->next;
p->next = NULL;
p = q;
(p != NULL)
{
q = q->next;
p->next = current->next;
current->next = p;
p = q;
}
}
}
int LinkList_Length(LinkList* list)
{
TLinkList* sList = (TLinkList*)list;
int ret = -1;
if(sList!=NULL)
{
ret = sList->length;
}
return ret;
}
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)
{
TLinkList* sList = (TLinkList*)list;
int ret = (sList!=NULL) && (pos>=0) && (node!=NULL);
int i = 0;
if(ret)
{
if(pos >= sList->length)
{
pos = sList->length;
}
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)
{
TLinkList* sList = (TLinkList*)list;
LinkListNode* ret =NULL;
int i = 0;
if((sList!=NULL)&&(pos>=0) && (pos<sList->length))
{
LinkListNode* current = (LinkListNode*)sList;
for(i=0; (i<pos)&&(current->next!=NULL); 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((sList!=NULL)&&(pos>=0)&&(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
[cpp] view
plaincopy
#include <stdio.h>
#include <stdlib.h>
#include "LinkList.h"
typedef struct _tag_Value
{
LinkListNode header;
int v;
}Value;
int main(void)
{
LinkList* list = LinkList_Create();
int i = 0;
Value v1, v2, v3, v4, v5;
v1.v=1, v2.v=2, v3.v=3, v4.v=4, v5.v=5;
LinkList_Insert(list, (LinkListNode*)&v1, 0);
LinkList_Insert(list, (LinkListNode*)&v2, 0);
LinkList_Insert(list, (LinkListNode*)&v3, 0);
LinkList_Insert(list, (LinkListNode*)&v4, 0);
LinkList_Insert(list, (LinkListNode*)&v5, 0);
Value* pV = NULL;
for(i=0; i<LinkList_Length(list); i++)
{
pV = (Value*)LinkList_Get(list, i);
printf("%d\n", pV->v);
}
while(LinkList_Length(list) > 0)
{
pV = (Value*)LinkList_Delete(list, LinkList_Length(list)-1);
printf("%d\n", pV->v);
}
LinkList_Destroy(list);
return 0;
}
相关文章推荐
- 数据结构(13)线性表
- 【暑假】[实用数据结构]前缀树 Trie
- 可视化的数据结构和算法
- MySQL索引背后的数据结构及算法原理
- 数据结构(12)哈希表
- 数据结构(11)无向图相关算法基础
- 数据结构(9)平衡查找树之B树
- 数据结构(8)平衡查找树之红黑树
- 数据结构(7)平衡查找树之2-3树
- 数据结构(6)二叉树
- 数据结构(5)优先级队列与堆排序
- B-tree B+tree 数据结构解析
- 数据结构(4)快速排序
- C源码@数据结构与算法->基数排序
- 数据结构(3)合并排序
- 数据结构(2)基本排序算法
- 程序员必须知道的10个算法和数据结构有哪些?
- 【数据结构与算法】折半查找算法(二分法)
- 数据结构上机实验之二分查找
- 【暑假专题训练#数据结构】