線性表的鏈式存儲結構的C語言實現


#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#include "io.h"
#include "math.h"
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 20 /* 存儲空間初始分配量 */

typedef int Status;/* Status是函數的類型,其值是函數結果狀態代碼,如OK等 */
typedef int ElemType;/* ElemType類型根據實際情況而定,這里假設為int */


Status visit(ElemType c)
{
printf("%d ",c);
return OK;
}

typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
typedef struct Node *LinkList; /* 定義LinkList */

/* 初始化順序線性表 */
Status InitList(LinkList *L)
{
*L=(LinkList)malloc(sizeof(Node)); /* 產生頭結點,並使L指向此頭結點 */
if(!(*L)) /* 存儲分配失敗 */
return ERROR;
(*L)->next=NULL; /* 指針域為空 */

return OK;
}

/* 初始條件:順序線性表L已存在。操作結果:若L為空表,則返回TRUE,否則返回FALSE */
Status ListEmpty(LinkList L)
{
if(L->next)
return FALSE;
else
return TRUE;
}

/* 初始條件:順序線性表L已存在。操作結果:將L重置為空表 */
Status ClearList(LinkList *L)
{
LinkList p,q;
p=(*L)->next; /* p指向第一個結點 */
while(p) /* 沒到表尾 */
{
q=p->next;
free(p);
p=q;
}
(*L)->next=NULL; /* 頭結點指針域為空 */
return OK;
}

/* 初始條件:順序線性表L已存在。操作結果:返回L中數據元素個數 */
int ListLength(LinkList L)
{
int i=0;
LinkList p=L->next; /* p指向第一個結點 */
while(p)
{
i++;
p=p->next;
}
return i;
}

/* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */
/* 操作結果:用e返回L中第i個數據元素的值 */
Status GetElem(LinkList L,int i,ElemType *e)
{
int j;
LinkList p; /* 聲明一結點p */
p = L->next; /* 讓p指向鏈表L的第一個結點 */
j = 1; /* j為計數器 */
while (p && j<i) /* p不為空或者計數器j還沒有等於i時,循環繼續 */
{
p = p->next; /* 讓p指向下一個結點 */
++j;
}
if ( !p || j>i )
return ERROR; /* 第i個元素不存在 */
*e = p->data; /* 取第i個元素的數據 */
return OK;
}

/* 初始條件:順序線性表L已存在 */
/* 操作結果:返回L中第1個與e滿足關系的數據元素的位序。 */
/* 若這樣的數據元素不存在,則返回值為0 */
int LocateElem(LinkList L,ElemType e)
{
int i=0;
LinkList p=L->next;
while(p)
{
i++;
if(p->data==e) /* 找到這樣的數據元素 */
return i;
p=p->next;
}

return 0;
}


/* 初始條件:順序線性表L已存在,1≤i≤ListLength(L), */
/* 操作結果:在L中第i個位置之前插入新的數據元素e,L的長度加1 */
Status ListInsert(LinkList *L,int i,ElemType e)
{
int j;
LinkList p,s;
p = *L;
j = 1;
while (p && j < i) /* 尋找第i個結點 */
{
p = p->next;
++j;
}
if (!p || j > i)
return ERROR; /* 第i個元素不存在 */
s = (LinkList)malloc(sizeof(Node)); /* 生成新結點(C語言標准函數) */
s->data = e;
s->next = p->next; /* 將p的后繼結點賦值給s的后繼 */
p->next = s; /* 將s賦值給p的后繼 */
return OK;
}

/* 初始條件:順序線性表L已存在,1≤i≤ListLength(L) */
/* 操作結果:刪除L的第i個數據元素,並用e返回其值,L的長度減1 */
Status ListDelete(LinkList *L,int i,ElemType *e)
{
int j;
LinkList p,q;
p = *L;
j = 1;
while (p->next && j < i) /* 遍歷尋找第i個元素 */
{
p = p->next;
++j;
}
if (!(p->next) || j > i)
return ERROR; /* 第i個元素不存在 */
q = p->next;
p->next = q->next; /* 將q的后繼賦值給p的后繼 */
*e = q->data; /* 將q結點中的數據給e */
free(q); /* 讓系統回收此結點,釋放內存 */
return OK;
}

/* 初始條件:順序線性表L已存在 */
/* 操作結果:依次對L的每個數據元素輸出 */
Status ListTraverse(LinkList L)
{
LinkList p=L->next;
while(p)
{
visit(p->data);
p=p->next;
}
printf("\n");
return OK;
}

/* 隨機產生n個元素的值,建立帶表頭結點的單鏈線性表L(頭插法) */
void CreateListHead(LinkList *L, int n)
{
LinkList p;
int i;
srand(time(0)); /* 初始化隨機數種子 */
*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL; /* 先建立一個帶頭結點的單鏈表 */
for (i=0; i<n; i++)
{
p = (LinkList)malloc(sizeof(Node)); /* 生成新結點 */
p->data = rand()%100+1; /* 隨機生成100以內的數字 */
p->next = (*L)->next;
(*L)->next = p; /* 插入到表頭 */
}
}

/* 隨機產生n個元素的值,建立帶表頭結點的單鏈線性表L(尾插法) */
void CreateListTail(LinkList *L, int n)
{
LinkList p,r;
int i;
srand(time(0)); /* 初始化隨機數種子 */
*L = (LinkList)malloc(sizeof(Node)); /* L為整個線性表 */
r=*L; /* r為指向尾部的結點 */
for (i=0; i<n; i++)
{
p = (Node *)malloc(sizeof(Node)); /* 生成新結點 */
p->data = rand()%100+1; /* 隨機生成100以內的數字 */
r->next=p; /* 將表尾終端結點的指針指向新結點 */
r = p; /* 將當前的新結點定義為表尾終端結點 */
}
r->next = NULL; /* 表示當前鏈表結束 */
}

int main()
{
LinkList L;
ElemType e;
Status i;
int j,k;
i=InitList(&L);
printf("初始化L后:ListLength(L)=%d\n",ListLength(L));
for(j=1;j<=5;j++)
i=ListInsert(&L,1,j);
printf("在L的表頭依次插入1~5后:L.data=");
ListTraverse(L);

printf("ListLength(L)=%d \n",ListLength(L));
i=ListEmpty(L);
printf("L是否空:i=%d(1:是 0:否)\n",i);

i=ClearList(&L);
printf("清空L后:ListLength(L)=%d\n",ListLength(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.data=");
ListTraverse(L);

printf("ListLength(L)=%d \n",ListLength(L));

ListInsert(&L,1,0);
printf("在L的表頭插入0后:L.data=");
ListTraverse(L);
printf("ListLength(L)=%d \n",ListLength(L));

GetElem(L,5,&e);
printf("第5個元素的值為:%d\n",e);
for(j=3;j<=4;j++)
{
k=LocateElem(L,j);
if(k)
printf("第%d個元素的值為%d\n",k,j);
else
printf("沒有值為%d的元素\n",j);
}

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);

j=5;
ListDelete(&L,j,&e); /* 刪除第5個數據 */
printf("刪除第%d個的元素值為:%d\n",j,e);

printf("依次輸出L的元素:");
ListTraverse(L);

i=ClearList(&L);
printf("\n清空L后:ListLength(L)=%d\n",ListLength(L));
CreateListHead(&L,20);
printf("整體創建L的元素(頭插法):");
ListTraverse(L);

i=ClearList(&L);
printf("\n刪除L后:ListLength(L)=%d\n",ListLength(L));
CreateListTail(&L,20);
printf("整體創建L的元素(尾插法):");
ListTraverse(L);


return 0;
}

 查找:線性表的順序結構常數階   鏈式 線性階

插入和刪除:線性表的順序結構線性階   鏈式 常數階


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM