這是在上數據結構課程時候的練習,以後拿過來隨時用。
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
typedef int elemtype;
#define TRUE 0
#define FALSE 1
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#if(1)
typedef struct LNode
{
struct LNode *next;
int date;
}*LinkList;
//typedef LNode *LinkList;
#endif
#if(0)
typedef struct LNode
{
struct LNode *next;
elemtype data;
};
#endif
void InitList(LinkList L)
{
L = (LinkList)malloc(sizeof(struct LNode));
if(!L)
{
exit(-1);
}
L->next = NULL;
}
void DestroyList(LinkList L)
{
LinkList q;
while(L)
{
q = L->next;
free(L);
L = q;
}
}
void ClearList(LinkList L)
{
LinkList p, q;
p = L->next; //p = L的話就銷燬了鏈表相當於DestroyList
while(p)
{
q = p->next;
free(p);
p = q;
}
L->next = NULL;
}
int ListEmpty(LinkList L)
{
if(L->next)
{
return FALSE;
}
return TRUE;
}
int ListLength(LinkList L)
{
int i = 0;
LinkList p = L->next; //應該設立一個新的指針代替L,
while(p)
{
i++;
p = p->next;
}
return i;
}
int GetElem(LinkList L, int i, elemtype *e)
{
int j;
LinkList p;
p = L;
for(j = 0; j < i; j++)
{
p = p->next;
}
if(!p)
{
return ERROR;
}
*e = p->date;
return OK;
}
int LocateElem(LinkList L, elemtype *e)
{
int i = 0;
LinkList p;
p = L->next;
while(p)
{
i++;
if(p->date == *e)
{
return i;
}
p = p->next;
}
return 0;
}
int PriorElem(LinkList L, elemtype cur_e, elemtype *pre_e)
{
LinkList p, q;
p = L->next;
while(p->next)
{
q = p->next;
if(q->date == cur_e)
{
*pre_e = p->date;
return OK;
}
p = q;
}
return INFEASIBLE;
}
int NextElem(LinkList L, elemtype cur_e, elemtype *next_e)
{
LinkList p; //remember it
p = L->next;
while(p->next)
{
if(p->date == cur_e)
{
*next_e = p->next->date;
return OK;
}
p = p->next;
}
return INFEASIBLE;
}
int ListInsert(LinkList L, int i, elemtype e)
{
int j = 1;
LinkList p = L, s;
if(i < 1)
{
return ERROR;
}
s = (LinkList)malloc(sizeof(struct LNode));
s->date = e;
if(i == 1)
{
s->next = L;
L = s;
}
else
{
while(p && j < i - 1)
{
p = p->next;
j++;
}
if(!p)
{
return ERROR;
}
s->next = p->next;
p->next = s;
}
return OK;
}
int ListDelete(LinkList L, int i, elemtype *e)
{
int j = 1;
LinkList p = L->next;
LinkList q = L;
while(j < i)
{
p = p->next;
q = q->next;
j++;
}
if(!p || j >= i)
{
return ERROR;
}
q->next = p->next;
*e = p->date;
free(p);
return OK;
}
void ListTraverse(LinkList L)
{
LinkList q = L;
while(q)
{
printf("%d ", q->date);
q = q->next;
}
//printf("\n\n");
}
#if(0)
void main()
{ // 除了幾個輸出語句外,主程序和main2-1.cpp很像
LinkList L = NULL; // 與main2-1.cpp不同
elemtype e, e0;
int i;
int j, k;
InitList(L);
for(j=1; j<=5; j++)
{
i = ListInsert(L, 1, &j);
}
printf("在L的表頭依次插入1~5後:L=");
ListTraverse(L); // 依次對元素調用print(),輸出元素的值
i = ListEmpty(L);
printf("L是否空:i=%d(1:是0:否)\n",i);
ClearList(L);
printf("清空L後:L=");
ListTraverse(L);
i = ListEmpty(L);
printf("L是否空:i=%d(1:是0:否)\n",i);
for(j=1; j<=10; j++)
{
ListInsert(L, j, &j);
}
printf("在L的表尾依次插入1~10後:L=");
ListTraverse(L);
GetElem(L, 5, &e);
printf("第5個元素的值爲%d\n",e);
for(j=0; j<=1; j++)
{
k = LocateElem(L, &j);
if(k)
{
printf("第%d個元素的值爲%d\n",k,j);
}
else
{
printf("沒有值爲%d的元素\n",j);
}
}
for(j=1;j<=2;j++) // 測試頭兩個數據
{
GetElem(L, j, &e0); // 把第j個數據賦給e0
i = PriorElem(L, e0, &e); // 求e0的前驅
if(i == INFEASIBLE)
printf("元素%d無前驅\n", e0);
else
printf("元素%d的前驅爲%d\n", e0, e);
}
for(j=ListLength(L)-1; j<=ListLength(L); j++) // 最後兩個數據
{
GetElem(L, j, &e0); // 把第j個數據賦給e0
i=NextElem(L, e0, &e); // 求e0的後繼
if(i == INFEASIBLE)
{
printf("元素%d無後繼\n",e0);
}
else
{
printf("元素%d的後繼爲%d\n", e0, e);
}
}
k = ListLength(L); // k爲表長
for(j=k+1; j>=k; j--)
{
i = ListDelete(L, j, &e); // 刪除第j個數據
if(i == ERROR)
{
printf("刪除第%d個元素失敗\n",j);
}
else
{
printf("刪除第%d個元素成功,其值爲%d\n", j, e);
}
}
printf("依次輸出L的元素:");
ListTraverse(L);
DestroyList(L);
printf("銷燬L後:L=%u\n",L);
}
#endif
void main()
{
LinkList L = NULL;
int i, j;
InitList(L);
for(j=1; j<=5; j++)
{
i = ListInsert(L, 1, j);
}
printf("在L的表頭依次插入1~5後:L=");
ListTraverse(L); // 依次對元素調用print(),輸出元素的值
}