No.28 我與代碼的日常:順序表的基本操作

學習不易,需要堅持。

#pragma once
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int SLDataType ;

typedef struct SeqList
{
	SLDataType* array ;
	int capacity ;
	int size ;
}SeqList ;

//初始化&銷燬
void SeqListInit(SeqList* sl, size_t capacity) ;
void SeqListDestroy(SeqList* sl) ;

//增刪查改
//尾插
void SeqListPushBack(SeqList* sl, SLDataType data) ;

//頭插
void SeqListPushFront(SeqList* sl, SLDataType data) ;

//尾刪
void SeqListPopBack(SeqList* sl) ;

//頭刪
void SeqListPopFront(SeqList* sl) ;

//打印
void SeqListPrint(SeqList* sl) ;

//內部接口
void CheckCapacity(SeqList* sl) ;

//獲取元素
void GetElem(SeqList* sl, int i, SLDataType* e) ;

//表中間插入操作
void SeqListInsert(SeqList* sl, size_t pos, SLDataType data) ;

//表中間刪除操作
void SeqListDelete(SeqList* sl, size_t pos) ;

//在順序表中查詢元素
int SeqListFind(SeqList* sl, SLDataType data) ;

//刪除遇到的指定的第一個元素
void SeqListRemove(SeqList* sl, SLDataType data) ;

//修改pos所在下標對應的元素
void SeqListModify(SeqList* sl, size_t pos, SLDataType data) ;

//刪除遇到所有的指定元素
void SeqListRemoveAll(SeqList* sl, SLDataType data) ;

//冒泡排序
void SeqListBubbleSort(SeqList* sl) ;

//折半查找(二分查找)
int SeqListBinarySearch(SeqList* sl, SLDataType data) ;

//SeqList.c
#include "SeqList.h"

//初始化
void SeqListInit(SeqList* sl, size_t capacity) 
{
	sl->capacity = capacity ;
	sl->size = 0 ;
	sl->array = (SLDataType *) malloc (capacity * sizeof(SLDataType)) ;
	assert(sl->array != NULL) ;
	printf("初始化成功!元素個數爲%d\n",sl->size) ;
}

//銷燬
void SeqListDestroy(SeqList* sl) 
{
	assert(sl != NULL) ;
	free(sl->array) ;
	sl->array = NULL ; //防禦性代碼
	sl->capacity = sl->size = 0 ;
	printf("銷燬成功!元素個數爲%d\n",sl->size) ;
}

//尾插
void SeqListPushBack(SeqList* sl, SLDataType data) 
{
	assert(sl != NULL) ;
	CheckCapacity(sl) ;
	sl->array[sl->size] = data ;
	sl->size++ ;
	//printf("尾插成功!元素個數爲%d\n",sl->size) ;
}

//尾刪
void SeqListPopBack(SeqList* sl)
{
	assert(sl != NULL) ;
	if(sl->size == 0)
	{
		printf("此表本爲空,無法刪除!\n") ;
	}
	else
	{
	sl->size-- ;
	printf("尾刪成功!元素個數爲%d\n",sl->size) ;
	}
}

//頭插
void SeqListPushFront(SeqList* sl, SLDataType data)
{
	int i = 0 ;
	assert(sl != NULL) ;
	CheckCapacity(sl) ;
	for(i=sl->size-1; i>=0; i--)
	{
		sl->array[i+1] = sl->array[i] ;  /****************************/ 
	}
	sl->array[0] = data ;
	sl->size++ ;
	printf("頭插成功!元素個數爲%d\n",sl->size) ;
}

//打印
void SeqListPrint(SeqList* sl)
{
	int i = 0 ;
	for(i=0; i<sl->size; i++)
	{
		printf(" %d ", sl->array[i]) ;
	}
	printf("\n打印成功!元素個數爲: %d\n",sl->size) ;
}

//內部接口
void CheckCapacity(SeqList* sl) 
{
	int i = 0 ;
	//申請空間
	int newCapacity = sl->capacity * 2 ;
	SLDataType * newArray = (SLDataType*) malloc (newCapacity * sizeof(SLDataType)) ;
	assert(newArray) ;
	//搬運
	//int i = 0 ;
	for(i=0; i<sl->size; i++)
	{
		newArray[i] = sl->array[i] ;
	}
	//釋放舊的空間
	free(sl->array) ;
	//再保存新的
	sl->array = newArray ;
	sl->capacity = newCapacity ;
}

//獲得某位置的元素
void GetElem(SeqList* sl, int i, SLDataType* e)
{
	//若表長爲0,或者i不在正確的範圍內,則提示操作錯誤
	if(sl->size == 0 || i<1 || i>sl->size)
	{
		printf("獲取操作失敗!\n") ;
	}
	//若i的位置合法,則打印
	else
	{
		*e = sl->array[i-1] ;
		printf("獲取成功,array[%d]爲: %d\n", i-1,*e) ;
	}
}

//表中間插入操作
void SeqListInsert(SeqList* sl, size_t pos, SLDataType data)
{
	//i爲數據下標
	int i = 0 ;
	assert(sl) ;
	CheckCapacity(sl) ;
	assert((int)pos >= 0 && (int)pos <= sl->size) ;
	for(i=sl->size-1; i>=pos; i--)
	{
		sl->array[i+1] = sl->array[i] ;
	}
	sl->array[pos] = data ;
	sl->size++ ;
}

//表中間刪除操作
void SeqListDelete(SeqList* sl, size_t pos) 
{
	//i 爲數據下標
	int i = 0 ;
	assert(sl) ;
	assert((int)pos>=0 && (int)pos<=sl->size-1) ;
	for(i=pos+1; i<sl->size; i++)
	{
		sl->array[i-1] = sl->array[i] ;
	}
	sl->size-- ;
}

//在順序表中查詢元素
int SeqListFind(SeqList* sl, SLDataType data)
{
	//若在順序表中找到該元素,則返回其下標,否則返回-1
	int i = 0 ;
	assert(sl != NULL) ;
	for(i=0; i<sl->size; i++)
	{
		if(sl->array[i] == data)
		{
			return i ;
		}
	}
	return -1 ;
}

//刪除遇到的指定的第一個元素
void SeqListRemove(SeqList* sl, SLDataType data) 
{
	int pos = SeqListFind(sl, data) ;
	if(pos != -1)
	{
		SeqListDelete(sl, pos) ;
	}
}

//修改pos所在下標對應的元素
void SeqListModify(SeqList* sl, size_t pos, SLDataType data) 
{
	assert(sl != NULL) ;
	assert((int)pos>=0 && (int)pos<=sl->size-1) ;
	sl->array[pos] = data ;
}


//刪除遇到所有的指定元素
void SeqListRemoveAll(SeqList* sl, SLDataType data) 
{
	int j = 0 ;
	int i = 0 ;
	for(i=0; i<sl->size; i++)
	{
		if(sl->array[i] != data)
		{
			sl->array[j++] = sl->array [i] ;
		}
	}
	sl->size = j ;
}

//比較大小
static void Swap(int* a, int* b)
{
	int tmp = *a ;
	*a = *b ;
	*b = tmp ;
}

//冒泡排序
void SeqListBubbleSort(SeqList* sl)
{
	int i = 0 ;
	int j = 0 ;
	assert(sl != NULL) ;
	for(i=0; i<sl->size-1; i++)
	{
		for(j=0; j<sl->size-1-i; j++)
		{
			if(sl->array[j] > sl->array[j+1])
			{
				Swap(sl->array+j, sl->array+j+1) ;//與 Swap(&sl->array[j],&sl->array[j+1])等價
			}
		}
	}
}

//折半查找(二分查找)
int SeqListBinarySearch(SeqList* sl, SLDataType data)
{
	//left和right均爲下標,範圍是[left, right] ,左閉右閉區間
	int left = 0 ;
	int right = sl->size-1 ;
	int mid = 0 ;
	while(left <= right)
	{
		mid = (right-left)/2 + left ;
		if(data == sl->array[mid])
		{
			return mid ;
		}
		else if(data < sl->array[mid])
		{
			right = mid - 1 ;
		}
		else 
		{
			left = mid+ 1 ;
		}
	}
	return -1 ;
}

//main.c
#include "SeqList.h"

int main()
{
	SeqList sl ;
	SLDataType e ;
	int BinarySearchRet = 0 ;
	printf("----------順序表的基本操作----------\n") ;
	printf("\n初始化:\n") ;
	SeqListInit(&sl, 10) ;
	printf("\n尾插: \n") ;
	SeqListPushBack(&sl, 1) ;
	SeqListPushBack(&sl, 2) ;
	SeqListPushBack(&sl, 3) ;
	SeqListPushBack(&sl, 4) ;
	SeqListPushBack(&sl, 5) ;
	SeqListPushBack(&sl, 9) ;
	SeqListPushBack(&sl, 5) ;
	SeqListPushBack(&sl, 8) ;
	SeqListPushBack(&sl, 5) ;
	SeqListPushBack(&sl, 5) ;
	SeqListPushBack(&sl, 5) ;
	SeqListPrint(&sl) ;
	printf("\n尾刪: \n") ;
	SeqListPopBack(&sl) ;
	SeqListPrint(&sl) ;
	printf("\n頭插: \n") ;
	SeqListPushFront(&sl, 10) ;
	SeqListPrint(&sl) ;
    printf("\n獲取元素: \n") ;
	GetElem(&sl, 1,&e) ;
	printf("\n插入元素:\n") ;
	SeqListInsert( &sl, 3, 99) ;
    SeqListPrint(&sl) ;
	printf("\n刪除元素:\n") ;
   SeqListDelete(&sl, 2) ;
	 SeqListPrint(&sl) ;
	 printf("\n刪除遇到的第一個元素:\n") ;
	SeqListRemove(&sl, 5) ;
	SeqListPrint(&sl) ;
	printf("\n修改指定位置的元素: \n") ;
	SeqListModify(&sl, 3, 333) ;
	SeqListPrint(&sl) ;
	printf("\n刪除遇到的指定的所有元素:\n") ;
	SeqListRemoveAll(&sl, 5) ;
	SeqListPrint(&sl) ;
	printf("\n排序\n") ;
	SeqListBubbleSort(&sl) ;
	SeqListPrint(&sl) ;
	printf("\n二分查找:\n") ;
	BinarySearchRet = SeqListBinarySearch(&sl, 333) ;
	printf("\n二分查找到的下標是:[%d]\n", BinarySearchRet) ;
	printf("\n銷燬:\n") ;
	SeqListDestroy(&sl) ;
	printf("\n") ;
	return 0 ;
}

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

學習不易,需要堅持。

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