【数据结构】顺序表、链表

本文详细介绍了顺序表和链表的基本概念、创建方法、扩容、插入和删除操作,以及查找元素、判断大小和空性等实用功能。
摘要由CSDN通过智能技术生成

写的不好,欢迎批评指正。

顺序表

顺序表是一种支持随机访问下标的数据结构。通常用数组进行实现。

typedef int SQDataType;

typedef struct SeqList{
	SQDatatype* arr;
	size_t size;
	size_t capacity;
}SeqList;

顺序表的创建

SeqList* SeqCreate()
{
	SeqList* ptr = (SeqList*)malloc(sizeof(SeqList));
	if(ptr == NULL)
	{
		perror("malloc fail");
		return NULL;
	}
	ptr->arr = NULL;
	ptr->size = 0;
	ptr->capacity = 0;
	return ptr;
}

顺序表的扩容

void SeqCheckCapacity(SeqList* ptr)
{
	assert(ptr);
	if(ptr->size * sizeof(SQDataType) == ptr->capacity)
	{
		size_t NewCapacity = ptr->capacity == 0 ? sizeof(SQDataType) : 2 * ptr->capacity;
		SQDataType* tmp = (SQDataType*)realloc(ptr->arr, NewCapacity);
		if(tmp == NULL)
		{
			perror("cealloc fail");
			return;
		}
		ptr->arr = tmp;
	}
}

顺序表尾插

void SeqBackPush(SeqList* ptr, SQDataType x)
{
	assert(ptr);
	SeqCheckCapacity(ptr);
	ptr->arr[ptr->size] = x;
	ptr->size++;
}

顺序表尾删

void SeqBackPop(SeqList* ptr)
{
	assert(ptr);
	ptr->size--;
}

顺序表头插

void SeqFrontPush(SeqList* ptr, SQDataType x)
{
	assert(ptr);
	SeqCheckCapacity(ptr);
	for(int i = ptr->size - 1; i > 0; i--)// 执行size - 1次
	{
		ptr->arr[i] = ptr->arr[i - 1];
	}
	ptr->arr[0] = x;
	ptr->size++;
}

顺序表头删

void SeqFrontPop(SeqList* ptr)
{
	assert(ptr);
	assert(ptr->size);
	SeqCheckCapacity(ptr);
	for(int i = 0; i < ptr->size - 1; i++)// 执行size - 1次
	{
		ptr->arr[i] = ptr->arr[i + 1];
	}
	ptr->size--;
}

在随机位置后插入值

void SeqInsert(SeqList* ptr, SQDataType x, int pos)/pos为要插入的位置下标
{
	SeqCheckCapacity(ptr);
	assert(pos <= ptr->size - 1);
	int len = ptr->size;
	for(int i = len; i > pos, i--)
	{
		ptr->arr[i] = ptr->arr[i - 1];
	}
	ptr->arr[pos + 1] = x;
}

查找某个元素

int SeqFind(SeqList* ptr, SQDataType x)
{
	int len = ptr->size;
	for(int i = 0; i < len; i++)
	{
		if(ptr->arr[i] == x)
		{
			return i;
		}
	}
	return -1;
}

顺序表的大小

size_t SeqSize(SeqList* ptr)
{
	assert(ptr);
	return ptr->size;
}

判断顺序表是否为空

int SeqEmpty(SeqList* ptr)
{
	if(ptr->size == 0)
	return 1;

	else
	return 0;
}

销毁顺序表

void Destroy(SeqList* ptr)
{
	free(ptr->arr);
	ptr->arr = NULL;
	ptr->size = 0;
	ptr->capacity = 0;
	free(ptr);
}

链表

链表分为单链表和双链表,带或不带哨兵位,是否循环。
以下为单向不带哨兵位不循环链表。

typedef int LTDataType;

typedef struct ListNode{
	LTDataType val;
	struct ListNode* next;
}Node;

链表节点的创建

Node* CreateNode()
{
	Node* ptr = (Node*)malloc(sizeof(Node));
	if(ptr == NULL)
	{
		perror("malloc fail");
		return NULL;
	}
	ptr->val = 0;
	ptr->next = NULL;
}

链表的头插

void ListHeadPush(Node** pphead, LTDataType x)
{
	Node* NewNode = CreateNode();
	NewNode->next = *pphead;
	NewNode->val = x;
	*pphead = NewNode;
}

链表的头删

void ListHeadPop(Node** phead)
{
	Node* del = *phead;
	assert(**phead && *phead);
	*phead = (*phead)->next;
	free(del);
	del = NULL;
}

链表的尾插

void ListBackPush(Node* phead, LTDataType x)
{
	Node* cur = phead;
	while(cur->next != NULL)
	{
		cur = cur->next;
	}
	Node* NewNode = CreateNode();
	cur->next = NewNode;
	NewNode->val = x;
}

链表的尾删

void ListBackPop(Node** pphead)
{
	Node* cur = phead;
	assert(cur);
	if(cur->next == NULL)//只有一个节点
	{
		free(cur);
		*pphead = NULL;
	}
	else
	{
		while(cur->next->next != NULL)//找倒数第二个节点
		{
			cur = cur->next;
		}
		Node* del = cur->next;
		free(del);
		cur->next = NULL;
	}
}

在随机位置后插入值

void ListInsert(Node** pphead, Node* Insert, LTDataType x)
{
	if(*pphead == NULL && Insert == NULL)
	{
		Node* NewNode = CreateNode();
		NewNode->val = x;
		NewNode->next = head;
		*pphead = NewNode;
	}
	else
	{
		assert(pphead && Insert && *pphead);
		Node* NewNode = CreateNode();
		NewNode->next = Insert->next;
		Insert->next = NewNode;
		NewNode->val = x;
	}
}

链表的大小

int ListSize(Node* phead)
{
	int count = 0;
	assert(phead);
	Node* cur = phead;
	while(cur)
	{
		cur = cur->next;
		count++;
	}
	return count;
}

查找某个元素

Node* ListFind(Node* phead, LTDataType x)
{
	Node* cur = phead;
	while(cur)
	{
		if(cur->val == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

判断是否为空

int ListEmpty(Node* phead)
{
	if(ListSize(phead))
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值