No.29 我與代碼的日常:單鏈表的基本操作(單向+不帶頭+不循環)

學習不易,需要堅持。

//SList.h
#pragma once

typedef int SLDataType ;

typedef struct SListNode
{
	int data ;
	struct SListNode* next ;
}SListNode ;

typedef struct SList
{
	struct SListNode* first ;
}SList ;

//初始化&銷燬
void SListInit(SList* list) ;

//銷燬
void SListDestroy(SList* list) ;

//頭插
void SListPushFront(SList* list, SLDataType data) ;

//頭刪
void SListPopFront(SList* list) ;

//打印
void SListPrint(SList* list) ;

//尾插
void SListPushBack(SList* list, SLDataType data) ;

//尾刪
void SListPopBack(SList* list) ;

//查找
SListNode* SListFind(SList* list, SLDataType data) ;

//在pos位置的節點後插入元素
void SListInsertAfter(SListNode* pos, SLDataType data) ;

//刪除pos位置後的第一個節點
void SListEraseAfter(SListNode* pos) ;

//刪除遇到的指定的第一個節點
void SListRemove(SList* list, SLDataType data) ;
//SList.c
#include "SList.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

//初始化
void SListInit(SList* list) 
{
	assert(list != NULL) ;
	list->first = NULL ;
}

//銷燬
void SListDestroy(SList* list) 
{
	SListNode* next ;
	SListNode* cur ;
	for(cur=list->first; cur!=NULL; cur=next)
	{
		next = cur->next ;
		free(cur) ;
	}
	list->first = NULL ;
}

//頭插
void SListPushFront(SList* list, SLDataType data) 
{
	SListNode* node = (SListNode*) malloc (sizeof(SListNode)) ;
	assert(node) ;
	node->data = data ;
	node->next = list->first ;
	list->first = node ;
}

//頭刪
void SListPopFront(SList* list) 
{
	SListNode* old_first = list->first ;
	assert(list) ; //有無鏈表
	assert(list->first != NULL) ; //有鏈表,鏈表裏是否有元素,若鏈表爲空,則刪除失敗
	list->first = list->first->next ;
	free(old_first) ;
}

//打印
void SListPrint(SList* list) 
{
	SListNode* cur ;
	assert(list) ;
	for(cur=list->first; cur!=NULL; cur=cur->next)
	{
		printf("%d-->", cur->data) ;
	}
	printf("NULL\n") ;
}

//尾插
void SListPushBack(SList* list, SLDataType data)
{
	SListNode* node = (SListNode*) malloc (sizeof(SListNode)) ;
	SListNode* lastone = list->first ;
	assert(list != NULL) ;
	for( ; lastone->next != NULL; lastone=lastone->next)
	{}
	assert(node != NULL) ;
	node->data = data ;
	node->next = lastone ->next ;
	lastone->next = node ;
}

//尾刪
void SListPopBack(SList* list)
{
	SListNode* cur ;
	SListNode* m ;
	assert(list != NULL) ;
	assert(list->first != NULL) ;
	if(list->first->next  == NULL)
	{
		//若鏈表爲空,則尾刪即爲頭刪
		SListPopFront(list) ;
		return ;
	}
	for(cur=list->first; cur->next->next != NULL; cur=cur->next)
	{
	}//找到倒數第二個節點
    m = cur->next ;
	cur->next = m->next ;
	free(m) ;
}

//查找
SListNode* SListFind(SList* list, SLDataType data)
{
	SListNode* cur = list->first ;
	for( ; cur!=NULL; cur=cur->next)
	{
		if(cur->data == data) 
		{
			return cur ;
		}
	}
	return NULL ;
}

//在pos位置的節點後插入元素
void SListInsertAfter(SListNode* pos, SLDataType data) 
{
	SListNode* node = (SListNode*) malloc (sizeof(SListNode)) ;
	assert(node != NULL ) ;
	node->data = data ;
	node->next = pos->next ;
	pos->next = node ;
}

//刪除pos位置後的第一個節點
void SListEraseAfter(SListNode* pos)
{
	SListNode* node = pos->next->next ;
	free(pos->next) ;
	pos->next = node ;
}

//刪除遇到的指定的第一個節點
void SListRemove(SList* list, SLDataType data)
{
	SListNode* prev = NULL ;
	SListNode* cur = list->first ;
	while(cur != NULL && cur->data != data)
	{
		prev = cur ;
		cur = cur->next ;
	}
	//要刪除的節點不存在
	if(cur == NULL )
	{
		return ;
	}
	//要刪除的節點若就是第一個節點
	if(prev == NULL)
	{
		//即頭刪
		SListPopFront(list) ;
		return ;
	}
	prev->next = cur->next ;
	free(cur) ;
}


//main.c
#include "SList.h"
#include <stdio.h>

SList list ;

void test1()
{
	//初始化&頭插
	SListInit(&list) ;
	SListPushFront(&list, 999) ;
	SListPushFront(&list, 3) ;
	SListPushFront(&list, 3) ;
	SListPushFront(&list, 5) ;
	SListPushFront(&list, 4) ;
	SListPushFront(&list, 3) ;
	SListPushFront(&list, 2) ;
	SListPushFront(&list, 1) ;
}

void test2()
{
	//頭刪
	test1() ;
	SListPopFront(&list) ;
}

void test3()
{
	//尾插
	test2() ;
	SListPushBack(&list, 1024) ;
}

void test4()
{
	//尾刪
	test3() ;
	SListPopBack(&list) ;
}

void test5()
{
	//在pos位置之後插入
	SListNode* n = SListFind(&list, 3) ;
	SListInsertAfter(n, 520) ;
}

void test6()
{
	//刪除pos後的第一個節點
	SListNode* n = SListFind(&list, 520) ;
	SListEraseAfter(n) ;
}

void test7()
{
	//刪除遇到的指定的第一個節點
	test6() ;
	SListRemove(&list, 3) ;
}
void test8()
{
	//銷燬單鏈表
	test7() ;
	SListDestroy(&list) ;
}


int main() 
{
	printf("頭插: \n") ;
	test1() ;
	SListPrint(&list) ;
	printf("\n頭刪: \n") ;
	test2() ;
	SListPrint(&list) ;
	printf("\n尾插: \n") ;
	test3() ;
	SListPrint(&list) ;
	printf("\n尾刪: \n") ;
	test4() ;
	SListPrint(&list) ;
	printf("\n查找:\n") ;
	printf("999地址爲: %p\n",SListFind(&list, 999) ) ;
	printf("\n在pos位置之後插入: \n") ;
	test5() ;
	SListPrint(&list) ;
	printf("\n刪除pos位置之後的第一個節點:\n") ;
	test6() ;
	SListPrint(&list) ;
	printf("\n刪除遇到的指定的第一個節點:\n") ;
	test7() ;
	SListPrint(&list) ;
	printf("銷燬:\n") ;
	test8() ;
	SListPrint(&list) ;
	printf("\n") ;
	return 0 ;
}

運行結果:
在這裏插入圖片描述

學習不易,需要堅持。

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