週末任務 單鏈表

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章