周末任务 单链表

原创 2012年03月30日 15:35:48

#include <stdio.h>
#include <malloc.h>

#define MAXSIZE 100
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define NULL 0

struct LNode
{
 int data;
 struct LNode * next;
};

typedef LNode * Link, * Position, Node;

struct LLink
{
 Link head, tail;
 int len;
};

typedef LLink LinkList;

//创建一个结点,其值为value。
int MakeNode(Link &p, int value)
{
 //p = (Link) malloc(sizeof(Node));
 p = (LNode * ) malloc(sizeof(Node));
 if (p == NULL)
 {
  return ERROR;
 }

 p->data = value;
 p->next = NULL;

 return OK;
}

//释放p所指向的结点。
void FreeNode(Link &p)
{
 free(p);
 p = NULL;
}

//构造一个空的线性链表L。
int InitList(LinkList &L)
{
 L.head = NULL;
 L.tail = NULL;
 L.len = 0;
 
 return OK;
}

//已知h指向线性链表L的第一个结点,将s所指结点插入到h之前。
int InsFirst(LinkList &L, Link h, Link s)
{
 if (s == NULL)
 {
  return ERROR;
 }

 s->next = h;
 L.head = s;
 if (L.tail == NULL)
 {
  L.tail = s;
 }
 L.len++;

 return OK;
}

//删除线性链表L中的第一个结点,并以q返回。
int DelFirst(LinkList &L, Link &q)
{
 if (L.head == NULL)
 {
  return ERROR;
 }
 
 q = L.head;
 L.head = q->next;

 if (q == L.tail)
 {
  L.head = NULL;
  L.tail = NULL;
 }
 L.len--;

 return OK;
}

//将指针s所指的一串结点链接在线性表L的尾部。
int Append(LinkList &L, Link s)
{
 if (s == NULL)
 {
  return ERROR;
 }

 L.tail->next = s;
 L.len++;

 while(s->next != NULL)
 {
  s = s->next;
  L.len++;
 }
 L.tail = s;

 return OK;
}

//删除线性链表L中的尾结点并以q返回。
int Remove(LinkList &L, Link &q)
{
 if (L.len == 0)
 {
  return ERROR;
 }

 Link p;
 p = L.head;
 while (p->next != L.tail)
 {
  p = p->next;
 }
 q = p->next;
 p->next = NULL;
 L.tail = p;
 L.len--;

 return OK;
}

//返回p指示线性链表L中第i个结点的位置,并返回OK,i值不合法时返回ERROR。
int LocatePos(LinkList L, int i, Link &p)
{
 int j;
 if (i < 0 || i > L.len)
 {
  return ERROR;
 }

 p = L.head;
 for (j = 1; j < i; j++)
 {
  p = p->next;
 }

 return OK;
}

//已知p指向线性链表L中的一个结点,返回p所指结点的直接前驱的位置。若无直接前驱,则返回NULL。
Position PriorPos(LinkList L, Link p)
{
 if (p == L.head->next)
 {
  return NULL;
 }

 Link q;
 q = L.head->next;
 while (q->next != p)
 {
  q = q->next;
 }

 return q;
}

//已知p指向线性链表L中的一个结点,返回p所指结点的直接后继的位置。若无直接后继,则返回NULL。
Position NextPos(LinkList L, Link p)
{
 if (p->next == NULL)
 {
  return NULL;
 }

 return p->next;
}

//已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之前。
int InsBefore(LinkList &L, Link &p, Link s)
{
 if (s == NULL || p == NULL)
 {
  return NULL;
 }

 Link q;
 q = PriorPos(L, p);
 if (q == NULL)
 {
  q = L.head;
 }
 q->next = s;
 s->next = p;
 //p = s;
 L.len++;

 return OK;
}

//已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之后。
int InsAfter(LinkList &L, Link &p, Link s)
{
 if (s == NULL || p == NULL)
 {
  return NULL;
 }

 if (p == L.tail)
 {
  L.tail = s;
 }
 s->next = p->next;
 p->next = s;
 L.len++;

 return OK;
}

//返回线性链表L中头结点的位置。
Position GetHead(LinkList L)
{
 return L.head;
}

//返回线性链表L中尾结点的位置。
Position GetLast(LinkList L)
{
 return L.tail;
}

//释放线性链表L。
int FreeList(LinkList &L)
{
 if (L.len == 0)
 {
  return OK;
 }

 Link p, q;
 p = GetHead(L);
 while (p != NULL)
 {
  q = p;
  p = p->next;
  free(q);
 }

 L.head = NULL;
 L.tail = NULL;
 L.len = 0;

 return OK;
}

//输出线性链表L中的各个结点,并输出头尾指针所指元素值。
int Display(LinkList L)
{
 int i;
 if (L.head == NULL)
 {
  return ERROR;
 }

 Link p = L.head;
 for (i = 1; i <= L.len; i++)
 {
  printf("%d ", p->data);
  p = p->next;
 }
 printf("\n");
 printf("head value : %d \n", L.head->data);
 printf("tail value : %d \n", L.tail->data);
 printf("\n");

 return OK;
}

int main()
{
 int i;
 Link p;
 Link q;
 LinkList La, Lb;

 //初始化线性链表La。
 if (!InitList(La))
 {
  return OVERFLOW;
 }

 for (i = 7; i >= 1; i = i -1)
 {
  MakeNode(p, i);
  InsFirst(La, La.head, p);
 }
 printf("链表La为:");
 Display(La);

 //初始化线性链表Lb。
 if (!InitList(Lb))
 {
  return OVERFLOW;
 }

 for (i = 17; i >= 11; i = i -1)
 {
  MakeNode(p, i);
  InsFirst(Lb, Lb.head, p);
 }
 printf("链表Lb为:");
 Display(Lb);

 //将链表Lb链接到链表La之后。
 printf("两个线性链表想链接La + Lb: \n");
 Append(La, Lb.head);
 Display(La);

 //删除首结点。
 DelFirst(La, q);
 printf("被删除的首结点值为:%d\n", q->data);
 FreeNode(q);
 Display(La);

 //删除尾结点。
 Remove(La, q);
 printf("删除链表L中的最后一个结点:%d\n",q->data);
 FreeNode(q);
 Display(La);

 //定位第六个元素结点,并用p指针指向该结点。
 LocatePos(La, 6, p);
 Display(La);
 printf("第六个元素结点数据:%d\n",p->data);

 //p结点的直接前驱。
 q = PriorPos(La, p);
 Display(La);
 printf("第六个元素结点数据:%d\n",p->data);
 printf("第六个元素结点的直接前驱数据是:%d\n",q->data);

 //p结点的直接后继。
 q = NextPos(La, p);
 Display(La);
 printf("第六个元素结点数据:%d\n",p->data);
 printf("第六个元素结点的直接后继数据是:%d\n",q->data);
 printf("\n");
 
 //在第六个结点前插入值为111的新结点。
 printf("在第六个结点前插入值为111的新结点。\n");
 MakeNode(q, 111);
 InsBefore(La, p, q);
 Display(La);

 //在原第六个结点后插入值为222的新结点。
 printf("在原第六个结点后插入值为222的新结点。\n");
 MakeNode(q, 222);
 InsAfter(La, p, q);
 Display(La);

 //输出线性链表La的表头结点。
 q = GetHead(La);
 printf("线性链表La中表头结点的值为:%d\n",q->data);

 //输出线性链表La的表尾结点。q = GetLast(La);
 printf("线性链表La中表尾结点的值为:%d\n",q->data);

 FreeList(La);
 Display(La);

 return 0;
}

单链表,双链表和循环链表之间的区别详解

链表是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每个节点里存到下一个节点的指针。由于不须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比顺序表O(logn)快...
  • zhongwen7710
  • zhongwen7710
  • 2014年09月06日 17:41
  • 7444

单链表 之c代码

我们知道数据结构就是数据及其相互关系,包括逻辑结构和物理结构。单链表的逻辑结构是一种一对一的线性关系,物理结构是利用节点把数据结合起来,在计算机中体现这种一对一的数据关系。单链表节点包括包含数据本身信...
  • tianxiaolu1175
  • tianxiaolu1175
  • 2015年08月18日 18:30
  • 820

单链表的实现(C++版)

// 带头节点单链表的C++实现 #include "stdafx.h" #include #include using namespace std; class CNode ...
  • piaopiaopiaopiaopiao
  • piaopiaopiaopiaopiao
  • 2014年05月12日 20:27
  • 6490

单链表的创建算法

单链表的创建算法        当一个序列中只含有指向它的后继结点的链接时,就称该链表为单链表。        单链表的示意图如下:                                ...
  • wp1603710463
  • wp1603710463
  • 2016年03月26日 23:34
  • 17837

单链表的合并,排序与翻转

1.单链表的合并:   合并两个有序(从小到大)链表,首先比较两链表第一个结点值的大小,将小的放入新的链表(创建的临时链表);然后将小的那条链表向后移动一个位置,重复比较。当然,在进行这些处理之前,先...
  • zhu_931
  • zhu_931
  • 2017年03月15日 23:11
  • 697

单链表之排序

题:编程实现单链表的排序。 答案:完整代码如下: // P167_example1.cpp : Defines the entry point for the console applicatio...
  • jimoshuicao
  • jimoshuicao
  • 2013年07月30日 16:40
  • 2926

c++实现单链表

#include #include using namespace std; typedef int DataType;struct LinkNode //创建一个节点 { DataTyp...
  • yangrujing
  • yangrujing
  • 2015年08月26日 12:07
  • 890

单链表的基本操作-----图形解析

首先我们需要思考的是为什么需要单链表呢? 单链表和顺序表相比较,又有什么优点呢? 在顺序表中,当我们需要头插,或者在顺序表的中间位置插入元素时,就必须将后面的元素一一后移,再将需要插入的元...
  • qq_34992845
  • qq_34992845
  • 2016年12月31日 01:12
  • 2366

将单链表拆分为两个特定的单链表

将一个给定的单链表拆分为两个特定的单链表
  • yfainaer
  • yfainaer
  • 2016年09月22日 21:16
  • 1386

2015年大二上-数据结构-链表(3)-单链表算法

1、设计一个算法,将一个带头结点的数据域依次为a1,a2,…,an(n≥3)的单链表的所有结点逆置,即第一个结点的数据域变为an,…,最后一个结点的数据域为a1。实现这个算法,并完成测试。 /* *C...
  • Annpion
  • Annpion
  • 2015年11月03日 12:28
  • 392
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:周末任务 单链表
举报原因:
原因补充:

(最多只允许输入30个字)