1. 程式人生 > >資料結構——單鏈表實現及操作(c語言)

資料結構——單鏈表實現及操作(c語言)

#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1  
#define OVERFLOW -2

typedef int Status;
typedef int ElemType;

typedef struct LNode
{
	ElemType data;
	struct LNode *next;
}LNode, *Link, *Position;

typedef struct 
{
	Link head, tail;
	int len;
}LinkList;

Status MakeNode(Link *p, ElemType e);
void FreeNode(Link *p);
Status InitList(LinkList *L);
Status ClearList(LinkList *L);
Status Destory(LinkList *L);
Status InsertList(LinkList *L, Link s);
void Traverse(LinkList *L);
void Append(LinkList *L, Link s);
Status Remove(LinkList *L, Link q);
Status InsAfter(LinkList *L, Link *p, Link s);
Status ListCurElem(Link p, ElemType e);
Status IsEmpty(LinkList *L);
int ListLength(LinkList *L);
Position GetHead(LinkList L);
Position GetTail(LinkList L);
Position PriorPos(LinkList L, Link p);
Position NextPos(LinkList L, Link p);
Position LocatePos(LinkList L, int i, Link *p);
Status compare(ElemType e1,ElemType e2);
Position LocateElem(LinkList L, ElemType e, Status (*compare)(ElemType, ElemType));
void visit(ElemType e);
Status ListTravese(LinkList L, void (*visit)(ElemType));

void main()
{
	Link p, s, h;
	LinkList L;
	Status i;
	int j;
	Link q;
	ElemType e;
	//Status comp;
	e = 88;

	q = NULL;

	i = InitList(&L);

	if(!i)   //初始化空的線性表L不成功
		exit(-1);   //異常退出

	for(j = 1; j <= 10; j++)
	{
		MakeNode(&p, j);
		InsertList(&L, p);
	}
	Traverse(&L);

	MakeNode(&s, 9);
	s->next = NULL;   //待插入的一連串結點的尾結點
	for(j = 4; j >= 1; j--)
	{
		MakeNode(&h, j*2);
		h->next = s;
		s = h;
	}
	Append(&L, h);
	printf("After append:\n");
	Traverse(&L);
	Remove(&L, q);
	printf("The new tail pointer is %d.\n", L.tail->data);
	

	p = L.head;   //使p指向頭結點
	for(i = 0; i < 3; i++)
	{
		p = p->next;
	}

	s = (Link)malloc(sizeof(LNode));
	s->data = 100;

	InsAfter(&L, &p, s);
	printf("After InsAfter:\n");
	ListCurElem(p, e);
	Traverse(&L);

	p = GetHead(L);
	printf("頭結點是%d\n", p->data);
	p = GetTail(L);
	printf("尾結點是%d\n", p->data);

	p = PriorPos(L, p);
	printf("p的直接前驅是%d\n", p->data);

	p = NextPos(L, p);
	printf("p的直接後繼是%d\n", p->data);

	p = LocatePos(L, 3, &p);
	printf("第三個元素的值%d\n", p->data);
	
	//comp = compare(p->next, 8);
	p = LocateElem(L, 8, compare);
	printf("第一個滿足compare()判定的值為%d\n", p->data);

	ListTravese(L, visit);

	Destory(&L);
}

//分配由p指向e的結點
Status MakeNode(Link *p, ElemType e)
{
	(*p) = (Link)malloc(sizeof(LNode));
	if(!(*p)) 
		return ERROR;

	(*p)->data = e;
	return OK;
}

void FreeNode(Link *p)
{
	free(*p);
	(*p) = NULL;
}

//創造一個空的線性表
Status InitList(LinkList *L)
{
	Link p;
	p = (Link)malloc(sizeof(LNode));
	if(!p)
		return ERROR;

	p->next = NULL;
	L->head = L->tail = p;
	L->len = 0;
	return OK;
}

//將線性表L重置為空表,並釋放原連結串列的空間
Status ClearList(LinkList *L)
{
	Link p, q;

	if(L->head != L->tail)
	{
		p = q = L->head->next;
		L->head = NULL;

		while(p < L->tail)
		{
			p = q->next;
			free(q);
			q = p;
		}

		free(q);

		L->tail = L->head;
		L->len = 0;
	}

	return OK;
}

//銷燬相信連結串列L, L不在存在
Status Destory(LinkList *L)
{
	ClearList(L);
	FreeNode(&(L->head));   //釋放頭結點
	L->tail = NULL;
	L->len = 0;
	return OK;
}

//將s所指結點插入線性表
Status InsertList(LinkList *L, Link s)   
{
	
	L->tail->next = s;
	L->tail = s;
	L->len++;
	return OK;
}

void Traverse(LinkList *L)
{
	Link p;
	p = L->head->next;
	int i;

	for(i = 0; i < L->len; i++)
	{

		printf("No.%d: %d\n", i, p->data);
		p = p->next;
	}
	printf("The length of list is %d.\n", L->len);
}

//將指標s所指(彼此以指標相鏈)的一串結點連結線上性表L的最後一個結點
//之後,並改變連結串列L的指標指向新的尾結點
void Append(LinkList *L, Link s)
{
	//if(!s)
	//	exit(-1);
//	L->tail->next = s;
//	while(!L->tail->next)
//	{
	//	L->tail = L->tail->next;
//	}
	 int i=1;  
    L->tail->next = s;  //s接到L的尾部  
    while(s->next)        //計算s的長度  
    {  
        i++;  
        s = s->next;  
    }  
    L->tail = s;        //L的尾指標變成s的尾指標  
    L->len+=i;          //增加長度 
	printf("i = %d\n", i);
}

//刪除線性表L中的尾結點並以q返回,改變連結串列L的尾指標指向新的尾結點
Status Remove(LinkList *L, Link q)
{
	q = L->head->next;
	while(q->next != L->tail)
	{
		q = q->next;
	}
	free(L->tail);
	L->tail = q;
	L->len -= 1;
	return OK;
}

//已知p指向線性連結串列L中的一個結點,將s所指結點插入在p所指結點之後,
//並修改指標p指向新插入的結點
Status InsAfter(LinkList *L, Link *p, Link s)
{
	s->next = (*p)->next;
	(*p)->next = s;
	
	(*p) = s;
	L->len += 1;
	
	return OK;
}

//已知p指向線性連結串列中的一個結點,用e更新p所指結點中資料元素的值
Status ListCurElem(Link p, ElemType e)
{
	p->data = e;
	return OK;
}

//若線性表為空,則返回TRUE,否則飯後FALSE
Status IsEmpty(LinkList *L)
{
	if(!L->head->next)
		return TRUE;
	else 
		return FALSE;
}

//返回線性表元素的個數
int ListLength(LinkList *L)
{
	return L->len;
}

//返回連結串列L中頭結點的位置
Position GetHead(LinkList L)
{
	return L.head->next;
}

//返回連結串列L中尾結點的位置
Position GetTail(LinkList L)
{
	return L.tail;
}

//已知p指向線性表L中的一個結點,返回p所指結點的直接前驅的位置
//若無前驅,返回NULL
Position PriorPos(LinkList L, Link p)
{
	Link q;
	q = L.head->next;
	if(p == q) return NULL;   //無前驅

	while(q->next != p)
		q = q->next;
	return q;
}

////已知p指向線性表L中的一個結點,返回p所指結點的直接後繼的位置
//若無後繼,返回NULL
Position NextPos(LinkList L, Link p)
{
	if(!p->next)
		return NULL;
	else 
		return p->next;
}

//返回p指示連結串列L中第i個結點的位置並返回OK, i值不合法是返回ERROR                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
Position LocatePos(LinkList L, int i, Link *p)
{
	int j;
	if(i<L.len)
	{
		(*p)= L.head;
		for(j = 0; j < i; j++)
		{
			(*p) = (*p)->next;
		}
		return (*p);
	}

	return ERROR;
}

Status compare(ElemType e1,ElemType e2)  
{  
    return e1==e2;  
}  

//返回線性連結串列L中第1個與e滿足函式compare()判定關係的元素的位置
Position LocateElem(LinkList L, ElemType e, Status (*compare)(ElemType, ElemType))
{
	Link p;
	p = L.head;
	do
	{
		p = p->next;
	}while(p && !compare(p->data, e) );  //找到第一個大於等於e的位置
	
	if(p ==NULL)
		return NULL;
	return p;
}

void visit(ElemType e)

{
	printf("%d  ", e);
} 

//依次對L的每個元素呼叫函式visit()。一旦visit()失敗,則操作失敗
Status ListTravese(LinkList L, void (*visit)(ElemType))
{
	Link p;
	p = L.head->next;
	int i;

	for(i = 0; i < L.len; i++)
	{
		visit(p->data);
		p = p->next;
	}
	printf("\n");
	return OK;
}

相關推薦

資料結構——單鏈實現操作c語言

#include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #d

資料結構之順序佇列的操作C語言

#include <stdio.h> #include <stdlib.h> #include <string.h> #define QUEUELEN 15 //資料結構的定義 typedef struct { char name[

單鏈的基本操作C語言//以整型為例

        單鏈表與陣列相似,但是單鏈表堆記憶體的運用更加的方便,能夠充分的利用零散的記憶體,在中間新增或者刪除一個或多個元素時不需要像陣列一樣移動大量的元素。單鏈表的操作中,涉及到單鏈表元素變化的許耀中指向指標的指標操作。        下面是單鏈表的兩種建立方式以及其

學習筆記——單鏈的基本操作C語言實現

線性表的儲存結構有順序儲存結構(順序表)和鏈式儲存結構(連結串列)兩種。順序表在之前的部落格有介紹過,不明白的朋友可檢視:靜態分配順序表的基本操作及動態分配順序表的基本操作。相對於順序表來說,連結串列稍微難一些,本人花了兩天的時間認真查看了一些資料,終於大致明白了一些東西。現

隊列的實現操作C語言描述

img tdi 定義數據 上一個 判斷 free 隊列的單鏈表 插入數據 尾指針 // 隊列的單鏈表實現 // 頭節點:哨兵作用,不存放數據,用來初始化隊列時使隊頭隊尾指向的地方 // 首節點:頭節點後第一個節點,存放數據 #include&

資料結構—連結串列的基本操作c語言程式碼

連結串列連結串列也是一種線性表,與順序表不同之處在於不像順序表佔據一段連續的儲存空間,而是將儲存單元分散在記憶體的任意地址上。連結串列結構中,儲存每個資料時候都會把記錄寫在連結串列的一個結點(node)中,每個結點之間由指標相連,形成如同鏈子的結構。結點(node):可以是一

資料結構之哈夫曼樹c語言

 哈夫曼樹 利用靜態連結串列建立赫夫曼樹,建樹過程中要求左子樹權值小於右子樹權值,求各結點的編碼。要求:葉子結點的個數n及結點值由鍵盤錄入。本題給出程式程式碼,要求修改以滿足測試要求.  #include "stdio.h" #include "malloc.h" #in

資料結構——單鏈實現

鏈式儲存特點 在鏈式儲存中,節點之間的儲存單元地址可能是不連續的。鏈式儲存中每個結點都包含兩部分:儲存元素本身的資料域和儲存結點地址的指標域。結點中的指標指向的是下一個結點,也就是儲存的下一個結點的地址。 鏈式儲存的實現 1.建立連結串列 在建立連結串列時,頭結點不儲存資料,

資料結構 單鏈實現 純程式碼

單鏈表操作函式原型宣告 node_t *list_init(); //顯示單鏈表 void display(node_t *head); //在單鏈表上查詢第i個節點的存放地址 node_t *find(node_t *head,int i); //在單鏈表上第I個節點後面

C/C++,資料結構單鏈實現約瑟夫環

約瑟夫環——圍成一圈,定義一個數值K,從任意位置開始計數,每走K步刪除當前位置結點,直到剩下最後一個結點,求最後一個結點//單鏈表結構以及Find函式參見 2016-1-2 13:56 發表部落格SLi

資料結構-佇列的建立使用連結串列

#include<iostream> #include<stdio.h> #include<malloc.h> #include<stdlib.h> using namespace std; typedef in

資料結構之 二叉查詢樹C語言實現

資料結構之 二叉查詢樹 1. 二叉查詢樹的定義 二叉查詢樹(binary search tree)是一棵二叉樹,或稱為二叉搜尋樹,可能為空;一棵非空的二叉查詢樹滿足一下特徵: 每個元素有一個關鍵字,並且任意兩個元素的關鍵字都不同;因此,所有的關鍵字都是唯

資料結構排序演算法之歸併排序c語言實現

博主身為大二萌新,第一次學習資料結構,自學到排序的時候,對於書上各種各樣的排序演算法頓覺眼花繚亂,便花了很長的時間盡力把每一個演算法都看懂,但限於水平有限,可能還是理解較淺,於是便將它們逐個地整理實現出來,以便加深理解。 歸併排序就是通過將一個具有n個key記錄的線性表,看

資料結構之二叉排序樹C語言實現

一、基本概念1.二叉排序樹        二叉排序樹(Binary sort tree,BST),又稱為二叉查詢樹,或者是一棵空樹;或者是具有下列性質的二叉樹:        (1)若它的左子樹不為空,則左子樹上所有節點的值均小於它的根節點的值;        (2)若它的右

經典演算法學習——單鏈實現氣泡排序帶頭結點

核心程式碼如下:Node *BubbleSort(Node *pNode){ int count = SizeList(pNode);//用來控制次數 Node *pMove;

資料結構學習筆記-迴圈連結串列C語言實現

  迴圈連結串列的概念主要就是讓單鏈表的尾節點的指標不為空並且指向頭節點。像這樣的迴圈連結串列和普通單鏈表除了判斷條件幾乎沒有任何區別,判斷條件就是從p->next是否為空改為p->next是否等於頭節點,如果等於頭節點則迴圈結束。#include <std

9.考研-資料結構-鏈棧的基本操作帶頭結點

// ConsoleApplication1.cpp : 定義控制檯應用程式的入口點。 // /* 鏈棧: 兩個特殊狀態: 1.棧空的狀態:lst.next=NULL 2.棧滿的狀態 可以認為無限大 兩

資料結構之串的模式匹配C語言實現

一、暴力匹配演算法(BF) BF全稱為Brute-Force,最簡單直觀的模式匹配演算法。 1.演算法思想 兩個字串進行匹配時,一個主串和一個模式串,就是按照我們最容易想到的演算法來進行匹配。用兩個變數i,j分別記錄主串和模式串的匹配位置,如果兩者在某個字

資料結構之樹的基本操作java版本

本部落格來自慕課網《資料結構探險之樹篇》,慕課網主講老師使用C++實現的,這裡我將其改為java實現,以下是對程式碼的幾點說明:二叉樹:所有節點的度都小於等於2二叉樹的遍歷:根據訪問根的順序:前序、中序、後序。二叉樹陣列實現:左孩子下標 = 父節點下標2 + 1;右孩子下標

資料結構——一元多項式的表示相加C語言

//一元多項式的表示及相加 #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #defi