【數據結構】C語言實現順序鏈表

這是在上數據結構課程時候的練習,以後拿過來隨時用。


#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(),輸出元素的值
}


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