建立連結串列並進行增加、刪減操作

banon發表於2024-04-23

題目:對順序表中的元素進行增加和刪除以及訪問

使用陣列實現線性表的特性,需要知道三個條件:陣列元素的容量、陣列有效的最後一個元素的下標

/*************************************************************************
*	file name:	LinkedList.c
*	author	 :  User_laubon@163.com
*	date	 :  2024/04/22
*	function :  該案例是掌握進行順序表建立、增刪改查等操作
* 	note	 :  None
*
* 	Copyright (c)  2023-2024   cececlmx@126.com   All right Reserved
* *************************************************************************/

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

//將建立順序表的要素設定成一個結構體
typedef struct table
{
	char * addr;            //陣列元素首地址
	unsigned int Size;		//陣列的容量
	int Last;				//陣列有效元素的最後一個元素的下標
}Tab;          				//將表格結構體重新命名成Tab




//建立一個順序表
Tab* Table_creat (unsigned int size)
{
	//1.建立一個表格指標,並賦予空間
	Tab* Manager = (Tab*)calloc(1,sizeof(Manager));
	
	//判斷申請堆空間是否申請成功
	if (NULL == Manager)
	{
		printf("堆空間申請失敗\n");
		exit(-1); 
	}
	
	//2.利用calloc為所有元素申請堆記憶體
	Manager->addr = (char *)calloc(size,sizeof(char));
	//判斷申請堆空間是否申請成功
	if (NULL == Manager->addr)
	{
		perror("calloc memory for manager is failed\n");
		exit(-1); 
	}
	
	//3.對管理順序表的結構體進行初始化(元素容量 + 最後元素下標)
	Manager->Size = size;	//對順序表中的容量進行初始化
	Manager->Last = -1;		//由於順序表為空,則最後元素下標初值為-1
	
	return Manager;
}



//向順序表中增加資料
bool TabAdd(Tab *Manager, char Data , int Data_site)
{
	
	bool Judg_IsFull = (Manager->Last + 1 == Manager->Size) ? true : false;
	if (Judg_IsFull)
	{
		printf("順序表中資料已滿,無法新增\n");
		exit(-1);
	}
	if (1 == Data_site)
	{
		//1.向資料表末尾增加資料
		Manager->addr[++Manager->Last] = Data;
		return true;
	}
	else if(2 == Data_site)
	{
		//2.向資料表開頭增加資料
		for (int i = Manager->Last;i >= 0;i--)
		{
			Manager->addr[i+1] = Manager->addr[i];
		}

		//把新元素新增到順序表的頭部,並且更新管理結構體中的元素下標+1
		Manager->addr[0] = Data;
		Manager->Last++;

		return true;
	}
	else
	{
		printf("資料位置型別輸入錯誤,注:1為資料尾部,2為資料開頭\n");
		return false;
	}	
}


//向資料表中刪除資料

bool TabDel(Tab *Manager, char DelData)
{
	//1.判斷順序表是否為空	
	bool Judg_Empty = (-1 == Manager->Last) ? true : false;
	if (Judg_Empty == true)
	{
		printf("順序表中資料為空,無法刪除\n");
		exit(-1);
	}
	
	int temp = -1;  //記錄要刪除的元素的下標

	//2.此時需要查詢目標值是否在順序表中
	for(int i = 0; i <= Manager->Last; ++i)
	{	
		//如果目標值和順序表中元素的值相同
		if (DelData == Manager->addr[i])
		{
			temp = i; //把目標元素的下標備份到變數temp中
			break;
		}
	}
	
	//3.如果順序表沒有目標值的元素則直接終止函式
	if (-1 == temp)
	{
		printf("DelData [%c] is not found\n", DelData);
		return false;
	}

	//4.如果找到了目標元素,則直接把該元素的後繼元素向前移動一個單位
	for (int i = temp ; i < Manager->Last ; ++i)
	{
		Manager->addr[i] = Manager->addr[i+1];
	}

	//5.由於刪除了一個元素,則需要讓順序表的有效元素下標-1
	Manager->Last--;
	return true;		
}




//遍歷順序表的元素

void TabList_Print(Tab *Manager)
{
	for (int i = 0; i <= Manager->Last; ++i)
	{
		printf("Element[%d] = %c\n",i,Manager->addr[i]);
	}
}



int main (int argc, char const * argv[])
{
	//1.建立順序表
	Tab * Manager = Table_creat (10);

	//2.向順序表中增加元素
	printf("輸入元素,1為資料尾部,2為資料開頭\n");
	TabAdd(Manager, 'a' , 1);
	TabAdd(Manager, 'v' , 1);
	TabAdd(Manager, 'd' , 2);

	//遍歷順序表中的元素
	TabList_Print(Manager);

	//3.刪除順序表中的元素
	char str[] = {'a','d','n'};
	TabDel(Manager, str[0]);
	TabDel(Manager, str[1]);
	TabDel(Manager, str[2]);

	//遍歷順序表中的元素
	TabList_Print(Manager);

	return 0;
}

相關文章