無頭結點單鏈表基本操作
linklist.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
typedef int DataType;
typedef struct ListNode
{
struct ListNode* pNext;
DataType _data;
}Node,*PNode;
// 連結串列的初始化
void SListInit(PNode* pHead);
//建立一個節點
PNode BuyListNode(DataType data);
// 尾插
void SListPushBack(PNode* pHead, DataType data);
// 尾刪
void SListPopBack(PNode* pHead);
// 頭插
void SListPushFront(PNode* pHead, DataType data);
// 頭刪
void SListPopFront(PNode* pHead);
// 在連結串列中查詢值為data的元素,找到後返回值為data的結點
PNode SListFind(PNode pHead, DataType data );
// 在pos位置插入值為data的結點
void SListInsert(PNode* pHead, PNode pos, DataType data);
// 刪除pos位置額結點
void SListErase(PNode* pHead, PNode pos);
// 計算連結串列長度
int SListSize(PNode pHead);
// 判斷連結串列是否為空
int SListEmpty(PNode pHead);
// 銷燬連結串列
void SListDestroy(PNode* pHead);
//列印連結串列
void print(PNode pHead);
linklist. c
#define _CRT_SECURE_NO_WARNINGS 1
#include "linklist.h"
//初始化
void SListInit(PNode* pHead)
{
assert(pHead); //因為pHead是外部實參的地址,外部已經定義,所以地址是一定存在的,不可能為空
//如果為NULL的話一定是出錯誤了,所以用assert斷言來提示
*pHead = NULL;
}
//尾插
void SListPushBack(PNode* pHead, DataType data)
{
assert(pHead);
if(*pHead == NULL)
*pHead = BuyListNode(data);
else
{
PNode pCur = *pHead;
#if 1
while(pCur->pNext) //當本節點的pNext為空是跳出,直接讓pCur->pNext指向要插入資料的節點
pCur = pCur->pNext;
#else
PNode pPre = NULL;
while(pCur)
{
pPre = pCur;
pCur = pCur->pNext; //這是不行的,因為pCur最後一定指向空才跳出
//如果為空的話,在下一條語句pCur->pNext就會出錯
}
pCur = pPre;
#endif
pCur->pNext = BuyListNode(data); //走到這一步pCur->pNext一定為空要插入節點,應該讓pCur->pNext指向新節點
}
}
//尾刪
void SListPopBack(PNode* pHead)
{
//三種情況1、0個 2、1個 3、多個
PNode pCur = *pHead;
PNode pPre = NULL;
assert(pHead);
if(*pHead == NULL)
{
printf("無節點可刪!\n");
return;
}
else if((*pHead)->pNext == NULL)
{
free(*pHead);
*pHead = NULL;
return;
}
while(pCur->pNext != NULL)
{
pPre = pCur;
pCur = pCur->pNext;
}
free(pCur);
pPre->pNext = NULL;
}
//頭插
void SListPushFront(PNode* pHead, DataType data)
{
PNode pCur;
assert(pHead);
if(*pHead == NULL)
{
*pHead = BuyListNode(data);
}
else
pCur = BuyListNode(data);
pCur->pNext = *pHead;
*pHead = pCur;
}
//頭刪
void SListPopFront(PNode* pHead)
{
PNode next;
assert(pHead);
if(*pHead == NULL)
{
printf("無資料可刪!\n");
return;
}
else
{
next = (*pHead)->pNext;
free(*pHead);
*pHead = next;
}
}
//查詢
PNode SListFind(PNode pHead, DataType data)
{
if(pHead == NULL)
return NULL;
while(pHead)
{
if(pHead->_data == data)
return pHead;
pHead = pHead->pNext;
}
return NULL;
}
// 在pos位置插入值為data的結點
void SListInsert(PNode* pHead, PNode pos, DataType data)
{
assert(pHead);
if(*pHead == NULL || pos == NULL)
return ;
if(*pHead == pos)
{
PNode pCur =BuyListNode(data);
pCur->pNext = *pHead;
*pHead = pCur;
}
else
{
PNode pCur = *pHead;
PNode pPre = NULL;
while( pCur != pos && pCur )
{
pPre = pCur;
pCur = pCur->pNext;
}
if(pCur)
{
PNode pNew = BuyListNode(data);
pNew->pNext = pCur;
pPre->pNext = pNew;
}
}
}
// 刪除pos位置額結點
void SListErase(PNode* pHead, PNode pos)
{
assert(pHead);
if(*pHead == NULL || pos == NULL)
return;
else if(pos == *pHead)
{
PNode pDel = *pHead;
*pHead = (*pHead)->pNext;
free(pDel);
}
else
{
PNode pCur = *pHead;
PNode pPre = NULL;
while(pCur!=pos && pCur)
{
pPre = pCur;
pCur = pCur->pNext;
}
if(pCur)
{
pPre->pNext = pCur->pNext;
free(pCur);
}
}
}
//計算連結串列長度
int SListSize(PNode pHead)
{
int count = 0;
if(pHead == NULL)
return 0;
else
{
while(pHead)
{
count++;
pHead = pHead->pNext;
}
}
return count;
}
//判斷為空
int SListEmpty(PNode pHead)
{
return pHead?1:0;
//if(pHead == NULL)
//{
// printf("連結串列為空!\n");
// return 0;
//}
//else
// printf("連結串列不為空!\n");
//return 0;
}
//清空連結串列
void SListDestroy(PNode* pHead)
{
PNode pCur = *pHead;
PNode pNext = NULL;
assert(pHead);
if(*pHead == NULL)
return;
else
{
*pHead = NULL;
while(pCur)
{
pNext = pCur->pNext;
free(pCur);
pCur = pNext;
}
}
}
//建立一個節點
PNode BuyListNode(DataType data)
{
PNode pNewNode = (PNode)malloc(sizeof(Node));
if(pNewNode == NULL)
{
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->pNext = NULL;
return pNewNode;
}
//列印連結串列
void print(PNode pHead)
{
if(pHead == NULL)
{
printf("NULL\n");
return;
}
while(pHead)
{
printf("%d->",pHead->_data);
pHead = pHead->pNext;
}
printf("NULL\n");
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "linklist.h"
void test();
void test1();
int main()
{
test();
return 0;
}
//測試
//查詢、任意插、任意刪、判空、銷燬
void test1()
{
PNode pHead = NULL;
SListInit(&pHead); //初始化
SListPushBack(&pHead,54); //尾插
SListPushBack(&pHead,465);
SListPushBack(&pHead,8);
SListPushBack(&pHead,78);
printf("%p\n",SListFind(pHead,465)); //列印465的節點(465的儲存地址)
printf("%d\n",SListFind(pHead,465)->_data); //列印465的節點的內容
SListInsert(&pHead,SListFind(pHead,54),100);//在54的位置插入一個數據100
print(pHead);
SListErase(&pHead,SListFind(pHead,100)); //刪除連結串列中資料為100的節點
print(pHead);
printf("節點的個數為:%d\n",SListSize(pHead)); //列印節點的個數
printf("%d\n",SListEmpty(pHead)); //判斷連結串列是否為空列印1不為空0為空
SListDestroy(&pHead); //銷燬連結串列
print(pHead);
}
//測試
//頭刪、頭插、尾刪、尾插
void test()
{
PNode pHead = NULL; //這裡直接賦值為空
SListInit(&pHead); //初始化
SListPushBack(&pHead,3); //尾插
SListPushBack(&pHead,4); //尾插
print(pHead);
SListPushFront(&pHead,6); //頭插
SListPushFront(&pHead,34);
SListPushFront(&pHead,54);
print(pHead);
SListPopBack(&pHead); //尾刪
SListPopFront(&pHead); //頭刪
print(pHead);
SListDestroy(&pHead);
}
相關推薦
無頭結點單鏈表基本操作
動態順序表 linklist.h #pragma once #include <stdio.h> #include <assert.h> #include <malloc.h> #include <stdlib.h&
C 無頭結點單鏈表若干操作
顧名思義就是從一開就是有用的結點 文章目錄 定義結構體 建立 輸出連結串列的值 在第i個位置前插入 刪除第i個節點 頭插法 尾插法 完整程式程式碼 定義結構體 typedef struct Node {
實現無頭結點單鏈表的基本操作函式
什麼是無頭結點連結串列??? singlelinkedlist.h標頭檔案 #ifndef __SINGLELINKEDLIST_H__ #include<stdio.h> #include<windows.h> #i
C++ 單鏈表基本操作分析與實現 連結串列 連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結
連結串列 連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:一個是儲存資料元素的資料域,另一個是儲存下一個結點地址的指標域。 相比於線性表
單鏈表 基本操作(元素遞增排序)
題目描述: 有一個帶頭節點的單鏈表L(至少有一個數據節點),設計一個演算法使其元素遞增有序排列。 解題思路: 由於單鏈表L中有一個以上的資料節點,首先構造一個只含有頭結點和首節點的有序單鏈表(只含有一個數據節點的單鏈表一定是有序的),然後掃描單鏈表L餘下的節點(由P指向),在有序單鏈表中
單鏈表基本操作(刪除連結串列中最大元素)
題目描述: 設計一個演算法,刪除一個單鏈表L中元素值最大的節點(假設這樣的節點唯一) 解題思路: 在單鏈表中刪除一個節點先要找到它的前驅節點,用指標p掃描整個單鏈表,pre指向節點p的前驅節點,在掃描時用maxp指向data域值最大的節點,maxpre指向maxp所指節點的前驅節點,當連
單鏈表 簡單題(單鏈表基本操作)
題目描述: 有一個帶頭結點的單鏈表L=(a1,b1,a2,b2,......an,bn),設計一個演算法將其拆分成兩個帶頭結點的單鏈表L1和L2,其中L1=(a1,a2,a3...an),L2=(b1,b2,b3....bn),要求L1使用L的頭結點。 解題思路: 利用原單鏈表L中的所有
C 資料結構中單鏈表基本操作
C中的typedef C中的typedef關鍵字作用是為一種資料型別定義一個新名字,這樣做的目的有兩個,一是給變數定義一個易記且意義明確的新名字,如: typedef unsigned char BYTE; 把unsigned char型別自命名為BYTE。另一個目的是
【資料結構】單鏈表-----基本操作
刪除指定位置的節點 void Erase(pList * pplist, pNode pos) { assert(pplist != NULL); assert(pos != NULL); if (*pplist == pos)//如果指向第一個節點
c++學習筆記—單鏈表基本操作的實現
用c++語言實現的單鏈表基本操作,包括單鏈表的建立(包括頭插法和尾插法建表)、結點的查詢、刪除、排序、列印輸出、逆置、連結串列銷燬等基本操作。 IDE:vs2013 具體實現程式碼如下: #include "stdafx.h" #include <malloc.h
單鏈表基本操作java實現
單鏈表基本操作 - java實現 1.單鏈表學習了好久,今天終於有時間寫一下了,帶頭結點的單鏈表上的基本操作,Java實現。 (1) 先來個介面 public interface IList { public void clear(); //清空連結串列 publi
Java單鏈表基本操作(七)--排序
單鏈表的插入排序比陣列麻煩,因為每次都都要從頭節點開始往後遍歷,頭節點也需要單獨處理 package listnode; /** * @author Gavenyeah * @date St
Java單鏈表基本操作(八)--合併兩個有序單鏈表
package listnode; /** * @author Gavenyeah * @date Start_Time:2016年4月1日 下午15:01:47 * @date End_Ti
c++實現單鏈表基本操作
程式媛決定好好學習寫程式碼 連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:一個是儲存資料元素的資料域,
資料結構之連結串列(1):單鏈表基本操作
1.前言 1.1宣告 文章中的文字可能存在語法錯誤以及標點錯誤,請諒解; 如果在文章中發現程式碼錯誤或其它問題請告知,感謝! 2.關於連結串列 2.1什麼是連結串列 連結串列可以看成一種在物理儲存單元上的非連續、非順序儲存的資料結構,該資
單鏈表基本操作的C語言實現(鏈式儲存結構)
#include<stdio.h> #include<stdlib.h> typedef int DataType; typedef struct Node{ DataType data; struct Node *next; }
單鏈表基本操作(1)
單鏈表基本操作 建立 建立 頭插入載入 尾插入載入 建立空連結串列 建立一個單鏈表,且為空表,並且返回連結串列 建立結構型別,在CS.c檔案中 typedef struct node{ int data; struc
Java單鏈表基本操作(六)--刪除重複節點;
package listnode; public class DeleteDuplecate_SingleList { public static void main(String[] arg
Java單鏈表基本操作(四)--單鏈表反轉
單鏈表反轉是筆試面試中考察最多的演算法之一,是單鏈表裡必須要熟練掌握的演算法。 /** * @author Gavenyeah * @date Start_Time:2016年4月1日 上午
建立無頭結點單鏈表
#include "stdafx.h" #include <iostream> using namespace std; typedef int ElemType; struct List