#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;
}