数据结构之链表(头指针链表的插入、删除、逆序)
2017-07-24 22:22
441 查看
链表也是一种线性表,区别于顺序表,链表是一种物理上不连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。头指针链表指不带头节点的链表,这样的链表在插入时需要考虑空表的情况,指定位置删除插入时也需要考虑是否在第一个节点处。因为头指针链表的很多操作都需要改变头指针。
下面是关于头指针链表的一些操作的实现。(包括头文件与源文件)
头文件:LinkList.h
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#define TRUE 1
#define FALSE 0
typedef int LinkData;
typedef struct _node
{
LinkData data;
struct _node *next;
}LinkList;
//头插法
int Insert_Head(LinkList **h,LinkData data);
//尾插法
int Insert_Last(LinkList **h,LinkData data);
//在第Pos个节点处插入,从1开始,没有第0个节点
int Insert_Pos(LinkList **h,int Pos,LinkData data);
//删除第Pos个节点,从1开始,没有第0个节点
int Delete_Pos(LinkList **h,int Pos);
//逆序链表
int Reverse_List(LinkList **h);
//打印链表
void Display(LinkList *h);
#endif
源文件:LinkList.c
#include <stdio.h>
#include <stdlib.h>
#include "LinkList.h"
//头插法
int Insert_Head(LinkList **h,LinkData data)
{
if (h == NULL)
{
return FALSE;
}
LinkList * node = (LinkList *)malloc(sizeof(LinkList)/sizeof(char));
if (node == NULL)
{
return FALSE;
}
node -> data = data;
node -> next = *h;
*h = node;
return TRUE;
}
//尾插法
int Insert_Last(LinkList **h,LinkData data)
{
if (h == NULL)
{
return FALSE;
}
LinkList * node = (LinkList *)malloc(sizeof(LinkList)/sizeof(char));
if (node == NULL)
{
return FALSE;
}
node -> data = data;
node -> next = NULL;
LinkList *tmp = *h;
if (tmp == NULL)
{
*h = node;
}
else
{
while(tmp -> next)
{
tmp = tmp -> next;
}
tmp -> next = node;
}
return TRUE;
}
//在第Pos个节点处插入,从1开始,没有第0个节点
int Insert_Pos(LinkList **h,int Pos,LinkData data)
{
if(h == NULL || Pos < 1)
{
printf ("插入失败\n");
return FALSE;
}
LinkList * node = (LinkList *)malloc(sizeof(LinkList)/sizeof(char));
if (node == NULL)
{
return FALSE;
}
node -> data = data;
if (*h == NULL) //空表
{
if (Pos != 1)
{
printf ("当前为空表,无法在第%d个节点位置插入\n",Pos);
free (node);
return FALSE;
}
node -> next = NULL;
*h = node;
}
else
{
if (Pos == 1)
{
node -> next = *h;
*h = node;
}
else
{
LinkList *tmp = *h;
int i;
for (i = 0;i < Pos - 2;i++)
{
tmp = tmp -> next;
if (tmp == NULL)
{
printf ("插入越界\n");
free (node);
return FALSE;
}
}
node ->next = tmp -> next;
tmp -> next = node;
}
}
return TRUE;
}
//删除第Pos个节点,从1开始,没有第0个节点
int Delete_Pos(LinkList **h,int Pos)
{
if (h == NULL || *h == NULL || Pos < 1)
{
printf ("删除失败\n");
return FALSE;
}
LinkList *tmp = *h;
if (Pos == 1)
{
*h = (*h) -> next;
free(tmp);
}
else
{
LinkList *tmp = *h;
int i;
for (i = 0;i < Pos - 2;i++)
{
tmp = tmp -> next;
if (tmp -> next == NULL)
{
printf ("删除越界\n");
return FALSE;
}
}
LinkList *p = tmp -> next;
tmp -> next = p -> next;;
free (p);
}
return TRUE;
}
//逆序链表
int Reverse_List(LinkList **h)
{
if (h == NULL || *h == NULL || (*h) -> next == NULL)
{
printf ("逆序失败\n");
return FALSE;
}
LinkList *pre = *h;
LinkList *cur = (*h) -> next;
LinkList *tmp;
while(cur)
{
tmp = cur -> next;
cur -> next = pre;
pre = cur;
cur = tmp;
}
(*h) -> next = NULL;
(*h) = pre;
return TRUE;
}
//打印链表
void Display(LinkList *h)
{
if (h == NULL)
{
return;
}
int count = 0;
while(h)
{
if(count++ % 4 == 0)
{
printf ("\n");
}
printf ("%8d",h -> data);
h = h -> next;
}
printf ("\n");
}
关于头指针链表的更多的功能,可以大家一起去实现。
下面是关于头指针链表的一些操作的实现。(包括头文件与源文件)
头文件:LinkList.h
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#define TRUE 1
#define FALSE 0
typedef int LinkData;
typedef struct _node
{
LinkData data;
struct _node *next;
}LinkList;
//头插法
int Insert_Head(LinkList **h,LinkData data);
//尾插法
int Insert_Last(LinkList **h,LinkData data);
//在第Pos个节点处插入,从1开始,没有第0个节点
int Insert_Pos(LinkList **h,int Pos,LinkData data);
//删除第Pos个节点,从1开始,没有第0个节点
int Delete_Pos(LinkList **h,int Pos);
//逆序链表
int Reverse_List(LinkList **h);
//打印链表
void Display(LinkList *h);
#endif
源文件:LinkList.c
#include <stdio.h>
#include <stdlib.h>
#include "LinkList.h"
//头插法
int Insert_Head(LinkList **h,LinkData data)
{
if (h == NULL)
{
return FALSE;
}
LinkList * node = (LinkList *)malloc(sizeof(LinkList)/sizeof(char));
if (node == NULL)
{
return FALSE;
}
node -> data = data;
node -> next = *h;
*h = node;
return TRUE;
}
//尾插法
int Insert_Last(LinkList **h,LinkData data)
{
if (h == NULL)
{
return FALSE;
}
LinkList * node = (LinkList *)malloc(sizeof(LinkList)/sizeof(char));
if (node == NULL)
{
return FALSE;
}
node -> data = data;
node -> next = NULL;
LinkList *tmp = *h;
if (tmp == NULL)
{
*h = node;
}
else
{
while(tmp -> next)
{
tmp = tmp -> next;
}
tmp -> next = node;
}
return TRUE;
}
//在第Pos个节点处插入,从1开始,没有第0个节点
int Insert_Pos(LinkList **h,int Pos,LinkData data)
{
if(h == NULL || Pos < 1)
{
printf ("插入失败\n");
return FALSE;
}
LinkList * node = (LinkList *)malloc(sizeof(LinkList)/sizeof(char));
if (node == NULL)
{
return FALSE;
}
node -> data = data;
if (*h == NULL) //空表
{
if (Pos != 1)
{
printf ("当前为空表,无法在第%d个节点位置插入\n",Pos);
free (node);
return FALSE;
}
node -> next = NULL;
*h = node;
}
else
{
if (Pos == 1)
{
node -> next = *h;
*h = node;
}
else
{
LinkList *tmp = *h;
int i;
for (i = 0;i < Pos - 2;i++)
{
tmp = tmp -> next;
if (tmp == NULL)
{
printf ("插入越界\n");
free (node);
return FALSE;
}
}
node ->next = tmp -> next;
tmp -> next = node;
}
}
return TRUE;
}
//删除第Pos个节点,从1开始,没有第0个节点
int Delete_Pos(LinkList **h,int Pos)
{
if (h == NULL || *h == NULL || Pos < 1)
{
printf ("删除失败\n");
return FALSE;
}
LinkList *tmp = *h;
if (Pos == 1)
{
*h = (*h) -> next;
free(tmp);
}
else
{
LinkList *tmp = *h;
int i;
for (i = 0;i < Pos - 2;i++)
{
tmp = tmp -> next;
if (tmp -> next == NULL)
{
printf ("删除越界\n");
return FALSE;
}
}
LinkList *p = tmp -> next;
tmp -> next = p -> next;;
free (p);
}
return TRUE;
}
//逆序链表
int Reverse_List(LinkList **h)
{
if (h == NULL || *h == NULL || (*h) -> next == NULL)
{
printf ("逆序失败\n");
return FALSE;
}
LinkList *pre = *h;
LinkList *cur = (*h) -> next;
LinkList *tmp;
while(cur)
{
tmp = cur -> next;
cur -> next = pre;
pre = cur;
cur = tmp;
}
(*h) -> next = NULL;
(*h) = pre;
return TRUE;
}
//打印链表
void Display(LinkList *h)
{
if (h == NULL)
{
return;
}
int count = 0;
while(h)
{
if(count++ % 4 == 0)
{
printf ("\n");
}
printf ("%8d",h -> data);
h = h -> next;
}
printf ("\n");
}
关于头指针链表的更多的功能,可以大家一起去实现。
相关文章推荐
- 数据结构之头指针链表的逆序、输出和指定位置的删除
- 数据结构作业代码保存-2.1 单向循环链表的建立,插入和删除,和指针移动
- 数据结构之单链表(尾插法)查找、插入和删除
- 数据结构之头指针链表de三种插入方式(头插法,尾插法,在pos处插入)
- C++ 数据结构的单链表的建立,插入,删除操作
- 数据结构——2 单链表插入和删除节点
- 数据结构——10 双向链表插入和删除节点
- 【数据结构】顺序表、单链表、循环链表的插入与删除
- 郝斌数据结构 28 链表的插入和删除算法的演示
- 【数据结构作业二】写出单链表结点的结构体类型定义及查找、插入、删除算法,并以单链表作存储结构,实现有序表的合并
- 数据结构 单链表插入删除操作(c语言实现)
- 数据结构:头插法、尾插法创建单链表,求链表长度、查找、插入、删除、合并
- 程序员面试宝典之数据结构基础----⑥双链表的建立,插入和删除
- 【程序员面试宝典】数据结构基础一单链表:创建|求长|插入|删除|排序|打印|逆置
- 数据结构学习二 数据结构之链表图解版【创建,遍历,删除,插入】
- 【数据结构】单链表(一)单链表的定义,插入,删除和查找操作
- 【1139】数据结构上机测试2-2:单链表操作B (逆序建表+重复元素删除)
- 【1139】数据结构上机测试2-2:单链表操作B (逆序建表+重复元素删除)
- 算法学习-数据结构之链表操作,创建,插入,删除,查找。
- 利用线性链表实现 初始化、插入数据、查看数据、删除数据、链表逆序、清除和销毁数据链表的功能