1. 程式人生 > >05單鏈表的簡單實現與測試

05單鏈表的簡單實現與測試

/*
*ListList.h
*/
#ifndef LINKLIST_H
#define LINKLIST_H

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

//讓使用者的資料包含這個結構體
typedef struct _LinkNode{
	struct LinkNode *next;
}LinkNode;
//連結串列結構體
typedef struct _List{
	LinkNode head;
	int size;
}List;
//初始化,建立一個新的連結串列
int InitList(List **list);
//線性表已經存在,銷燬線性表
void DestroyList(List **list);
//線性表L已經存在,將線性表置為空表
void ClearList(List *list);
//線性表已存在,若線性表為空,返回0,否則返回-1
int ListEmpty(const List list);
//線性表已存在,返回線性表的元素個數
int ListLength(const List *list);
//線性表已存在,1≤i≤ListLength(list); 將線性表中的第pos個位置的元素返回給
int GetElem(const List *list, const int pos, void **elem);
//線性表已存在,線上性表中的第pos個位置插入
void ListInsert(const List *list, int pos, void *elem);
//線性表已存在,刪除線性表中的第pos個位置元素,並用elem返回其值
void ListDelete(const List *list, int pos, void **elem);
//遍歷
void ListForeach(const List *list, void(*foreach)(void*));

#endif

/*
*ListList.c
*/

#include "LinkList.h"

//初始化成功返回0,失敗返回-1
int InitList(List **list)
{
	*list = (List*)malloc(sizeof(List));
	if (NULL == list){
		return -1;
	}
	(*list)->head.next = NULL;
	(*list)->size = 0;
	return 0;
}

void DestroyList(List **list)
{
	if (NULL != *list){
		free(*list);
		*list = NULL;
	}
}

void ClearList(List *list)
{
	if (NULL != list){
		list->head.next = NULL;
		list->size = 0;
	}
}

//線性表L已存在,若線性表為空,返回0,否則返回-1,傳入引數錯誤返回-2
int ListEmpty(const List *list)
{
	if (NULL != list){
		return -2;
	}
	if (0 != list->size){
		return -1;
	}
	return list->size;
}

//獲取元素個數,出錯返回-1
int ListLength(const List *list)
{
	if (NULL == list){
		return -1;
	}
	List *mylist = (List*)list;
	return mylist->size;
}

//根據位置獲取值
int GetElem(const List *list, const int pos, void **elem)
{
	if (NULL == list){
		return -1;
	}
	const List *mylist = list;
	if ((mylist->size - 1) < pos || pos < 0){
		return -1;
	}
	LinkNode *pCur = &(mylist->head);
	for (int i = 0; i < pos; i++){
		pCur = pCur->next;
	}
	*elem = pCur->next;
	return 0;
}

void ListInsert(const List *list, int pos, void *elem)
{
	//傳入引數判斷
	if (NULL == list || NULL == elem){
		return;
	}
	List *mylist = (List*)list;
	if (mylist->size < pos  || pos < 0){
		pos = mylist->size;
	}
	//找到pos位置結點的前一個結點
	LinkNode *pCur = &(mylist->head);
	for (int i = 0; i < pos; i++){
		pCur = pCur->next;
	}
	//將新結點插入連結串列
	((LinkNode*)elem)->next = pCur->next;
	pCur->next = (LinkNode*)elem;
	mylist->size++;
}

void ListDelete(const List *list, int pos, void **elem)
{
	if (NULL == list){
		return;
	}
	List *mylist = list;
	if (0 == mylist->size){
		return;
	}
	if (mylist->size < pos || pos < 0){
		return;
	}
	LinkNode *pCur = &(mylist->head);
	for (int i = 0; i < pos; i++){
		pCur = pCur->next;
	}
	//快取待刪除的結點
	LinkNode *pDel = pCur->next;
	//重新建立前驅後繼關係
	pCur->next = pDel->next;
	mylist->size--;
	*elem = pDel;
}

void ListForeach(const List *list, void(*foreach)(void*))
{
	if (NULL == list || NULL == foreach){
		return;
	}
	List *mylist = (List*)list;
	LinkNode *pCur = mylist->head.next;
	while (NULL != pCur){
		foreach(pCur);
		pCur = pCur->next;
	}
}

/*
*test.c
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "LinkList.h"

//使用者的資料,使用者的資料結構體的第一個成員必須包含規則的資料
typedef struct Maker{
	LinkNode node;
	char name[64];
	int age;
}Maker;

//測試輸出函式
void myPrint(void *data)
{
	Maker *maker = (Maker*)data;
	printf("name: %s, age:%d\n", maker->name, maker->age);
}

int main()
{
	Maker p1 = { NULL, "aaa1", 18 };
	Maker p2 = { NULL, "aaa2", 19 };
	Maker p3 = { NULL, "aaa3", 20 };
	Maker p4 = { NULL, "aaa4", 21 };
	Maker p5 = { NULL, "aaa5", 22 };
	List *list;
	//初始化連結串列測試
	if (InitList(&list) != 0){
		printf("初始化連結串列失敗\n");
		return -1;
	}
	//將資料插入連結串列
	ListInsert(list, 0, (LinkNode *)&p1);//使用者的定址範圍縮小
	ListInsert(list, 0, (LinkNode *)&p2);
	ListInsert(list, 0, (LinkNode *)&p3);
	ListInsert(list, 0, (LinkNode *)&p4);
	ListInsert(list, 0, (LinkNode *)&p5);
	//遍歷測試
	ListForeach(list, myPrint);
	//指定位置獲取元素測試
	Maker *m;
	if (-1 != GetElem(list, 2, &m)){
		printf("m->name:%s,m->age:%d\n", m->name, m->age);
	}
	//獲取連結串列個數測試
	printf("size:%d\n", ListLength(list));
	DestroyList(&list);
	system("pause");
	return 0;
}