/*
數據結構鏈表的生成,main函數部分
*/
#include <stdio.h>
#include <stdlib.h>
#include "Link_List.h"
/*
數據的存儲方式:
非線性--鏈表
*/
int main()
{
int Length = 0;
int TempValue = 0;
int Value;
PMyList PListHead = NULL;
PListHead = CreatList();//生成頭指針
printf("\n排序前:");
TraveList(PListHead);//遍歷
printf("\n排序後: ");
SortList(PListHead);
TraveList(PListHead);
InseElement(PListHead, 3, 5);
TraveList(PListHead);
printf("\n請輸入您要刪除的值: ");
scanf("%d", &Value);
DeleElement(PListHead, Value, &TempValue);
printf("\n要刪除的數據是: %d", TempValue);
printf("\n刪除後的鏈表爲: ");
TraveList(PListHead);
Length = LenList(PListHead);
printf("\n\n鏈表的長度爲:%d\n", Length);
return 0;
}
/*
鏈表的頭文件函數聲明部分
*/
#ifndef LINK_LIST_H_INCLUDED
#define LINK_LIST_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*
typedef struct _myList //新建一個鏈表的結構體
{
char name[10];
int score;
struct _myList* pNext;//每一個節點用於尋找到下一個節點的指針
}* pMylist, MyList;
*/
typedef struct _myList //每一個節點都有一個數據域和指針域
{
int date; //數據域
struct _mylist* pNext; //指針域--每一個節點都有一個指向下一個節點的指針(下一個節點的地址)
}* PMyList, MyList;
PMyList CreatList(); //用於生成一個節點
void TraveList(PMyList); //鏈表的遍歷
bool EmptyList(PMyList); //判斷鏈表是否爲空
bool FullList(PMyList); //判斷鏈表是否爲滿
int LenList(PMyList); //求鏈表的長度
void SortList(PMyList); //對鏈表進行排序
bool InseElement(PMyList, int, int); //在鏈表中插入數據,先輸入頭指針(PMyList),找到鏈表,在鏈表那個位置的前面(int)插入什麼數字(int)
bool DeleElement(PMyList, int, int *); //從鏈表中刪除數據,並把刪除的數據返回
#endif // LINK_LIST_H_INCLUDED
/*
實現文件部分
*/
#include <stdio.h>
#include <stdlib.h>
#include "Link_List.h"
PMyList CreatList(void)//節點的生成
{
int i, val; //臨時存放節點的值
int Len; //節點數
PMyList PListHead = (PMyList)malloc(sizeof(MyList));//動態生成頭結點的指針變量
if(NULL == PListHead)
{
printf("\n PListHead 動態分配內存失敗!");
exit(-1);
}
PMyList PTail = PListHead;//生成一個尾節點,這個節點一直指向鏈表最後一個元素的指針域中
PTail->pNext = NULL;
printf("\n節點總數:");
scanf("%d", &Len);
while(Len < 0)
{
printf("\n節點數必須是非負數,請重新輸入:");
scanf("%d", &Len);
fflush(stdin);
}
//1.用循環的方式來生成鏈表
for(i = 0; i < Len; i++)
{
printf("\n請輸入第%d個節點的值:", i + 1);
scanf("%d", &val);
PMyList PNew = (PMyList)malloc(sizeof(MyList)); //用動態分配內存的方式,生成了一個節點
if(NULL == PNew)
{
printf("\n PNew 動態分配內存失敗!");
exit(-1);
}
PNew->date = val; //爲生成的新節點的數據域進行賦值
PTail->pNext = PNew; //保證了PTail始終是指向最後一個節點的指針
PNew->pNext = NULL; //是最後一個節點的指針域爲空
PTail = PNew; //連同數據域一同賦值給PTail
}
return PListHead;
}
void TraveList(PMyList PListHead)//通過鏈表的頭地址來進行鏈表的遍歷
{
PMyList PTem = PListHead->pNext;//定義一個結構體指針,這個指針指向頭結點指向的下一個節點,如果這個節點的指針域爲空,則遍歷結束
printf("\n遍歷鏈表: ");
while(NULL != PTem)
{
printf("%d\t", PTem->date);
PTem = PTem->pNext;
}
return;
}
bool EmptyList(PMyList PListHead)//判斷鏈表是否爲空
{
if(NULL == PListHead->pNext )
{
return true;
}
return false;
}
bool FullList(PMyList PListHead)//判斷鏈表是否爲滿
{
return false;
}
int LenList(PMyList PListHead)
{
PMyList PTem = PListHead->pNext;//定義一個臨時的PMylist型的指針變量,並將這個指針指向第一個節點
int Length = 0;
while(NULL != PTem)
{
Length++;
PTem = PTem->pNext;//如果不爲空,將PTem下一個節點的地址賦給PTem
}
return Length;
}
void SortList(PMyList PListHead)//對鏈表中的數據進行排序
{
int len = LenList(PListHead);//獲取鏈表的長度
int i, j, temp;
PMyList PTemp1, PTemp2, PTemp3;
if(EmptyList(PListHead))
printf("鏈表爲空,不予以排序!");
else
{
for(i = 0, PTemp1 = PListHead->pNext; i < len - 1; i++, PTemp1 = PTemp1->pNext) //i = 0 ; i < len - 1; i++
{
for(j = 0, PTemp2 = PListHead->pNext; j < len - i - 1; j++, PTemp2 = PTemp2->pNext) //j = 0; j < len - i - 1; j++
{
PTemp3 = PTemp2->pNext;
if(PTemp2->date > PTemp3->date) //a[j] > a[j+1]
{
temp = PTemp2->date;
PTemp2->date = PTemp3->date;
PTemp3->date = temp;
}
}
}
}
return;
}
/*
假設鏈表的長度爲3,要求插入的元素位置爲2,值爲22
1.先判斷這個鏈表是否爲空,並且插入的元素位置是否是大於等於1 (>= 1), 最小值爲1
循環的作用是求出位置爲1的節點的指針域,這個指針域指向第二個節點
2.if語句用於判斷,插入的位置是否大於等於1或者鏈表是否爲空,如果爲空,返回false
3.PNew->date = Content;
動態構造一個新節點,新節點的值域爲所要插入的值
PMyList PTem2 = PTem->pNext;
再次構造一個臨時節點,這個節點的值爲第一個節點的指針域,即指向第二個節點
PTem->pNext = PNew;
將第一個節點的指針域指向新創建的變量
PNew->pNext = PTem2;
新創建的變量的指針域指向爲原來鏈表的第二個節點
bool InseElement(PMyList PListHead, int Place, int Content)//在鏈表PListHead中的第Place位置前插入Content
{
int i = 0;
PMyList PTem = PListHead; //定義一個指針,這個指針的指向和頭指針一樣
while(NULL != PTem && i < Place - 1)//如果這個鏈表不爲空,並且插入的位置最多大於鏈表長度(最大值+1)
{
PTem = PTem->pNext;
i++;
}
if(i > Place - 1 || NULL == PTem){
return false;
}
PMyList PNew = (PMyList)malloc(sizeof(MyList));
if(NULL == PNew)
{
printf("\n InseElement 中 PNew 內存分配失敗!\n");
exit(-1);
}
else
{
PNew->date = Content;
PMyList PTem2 = PTem->pNext;
PTem->pNext = PNew;
PNew->pNext = PTem2;
return true;
}
}
*/
bool DeleElement(PMyList PListHead, int Content, int * TemValu)
{
int Length = 0;
PMyList PTem1 = PListHead;
PMyList PTem2 = NULL;
if(EmptyList(PListHead))
{
printf("鏈表爲空,無法刪除!");
return false;
}
else
{
while(NULL != PTem1->pNext)//如果第一個節點不爲空
{
PTem2 = PTem1->pNext;//要刪除節點的前一個節點
if(Content == PTem2->date)
{
(*TemValu) = PTem2->date;
PTem1->pNext = PTem2->pNext;//將刪除節點的前一個節點指向要刪除節點的後一個節點
PTem2->pNext = NULL;//將要刪除的節點的指針域置爲空
free(PTem2);
return true;
}
PTem1 = PTem1->pNext;
Length++;
}
if(LenList(PListHead) == Length){
printf("鏈表中沒有這個數字!");
return false;
}
return true;
}
}
bool InseElement(PMyList PListHead, int Place, int Content)//(By Myslef)增加節點
{
PMyList PTem1 = PListHead; //頭指針
PMyList PTem2 = PListHead->pNext;//第一個節點
int i, len, Lenth = LenList(PListHead);//獲取鏈表的長度
if(EmptyList(PListHead) || Place <= 0 || Place > Lenth + 1)//如果要刪除的節點位置,小於零,或者大於節點 Length+1刪除失敗
{
return false;
}
else
{
for(i = 0; i < Place - 1; i++)//移動節點,使 PTem2 爲 Place 位置的節點,PTem2爲 place-1 位置的節點
{
PTem1 = PTem1->pNext;
PTem2 = PTem2->pNext;
}
PMyList PNew = (PMyList)malloc(sizeof(MyList));//創建一個新的節點
if(NULL == PNew)
{
printf("\n InseElement 中 PNew 內存分配失敗!\n");
exit(-1);
}
PNew->date = Content;
PTem1->pNext = PNew;
PNew->pNext = PTem2;
return true;
}
}