数据结构day2

一、顺序表

    数据项:

        存储元素的内存首地址

        表的容量

        元素的数量

    运算:

        创建、销毁、清空、插入、删除、访问、查询、修改、排序、遍历

    注意:

        1、要确保数据元素的连续性

        2、不能越界

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

#define TYPE int  //元素的类型
#define PH "%d "

//设计顺序表结构
typedef struct Array
{
	TYPE* ptr;     //存储元素的内存首地址
	size_t cal;    //表的容量
	size_t cnt;    //元素的数量
}Array;

//  创建
Array* create_array(size_t cal)
{
	//分配给顺序表结构内存
	Array* arr=malloc(sizeof(Array));
	//给数据元素分配内存
	arr->ptr=malloc(sizeof(TYPE)*cal);
	//记录表的容量
	arr->cal=cal;
	//初始化元素的数量
	arr->cnt=0;

	return arr;
}

//  销毁
void destroy_array(Array* arr)
{
	free(arr->ptr);
	free(arr);
}

//  清空
void clear_array(Array* arr)
{
	arr->cnt=0;
}

//  插入(不连续或者满了会失败)
bool insert_array(Array* arr,size_t index,TYPE date)
{
	// 判断表是否满
	if(arr->cnt >= arr->cal)	return false;
	//判断下标是否保持元素的连续性
	if(index > arr->cnt)	return false;
	
	//   数据向后移动
/*	for(int i=arr->cnt;i > index;i--)
	{
		arr->ptr[i]=arr->ptr[i-1];
	}*/
	memmove(arr->ptr+index+1,arr->ptr+index,(arr->cnt-index)*sizeof(TYPE));

	//插入数据
	arr->ptr[index]=date;
	arr->cnt++;
	return true;
}

//  删除
bool delete_array(Array* arr,size_t index)
{
	//判断下标是否存在
	if(index >= arr->cnt) return false;
	
	//数据内存向前移动
/*	for(int i=index;i< arr->cnt-1;i++)
	{
		arr->ptr[i]=arr->ptr[i+1];
	}*/
	
	memmove(arr->ptr+index,arr->ptr+index+1,(arr->cnt-index-1)*sizeof(TYPE));

	//数据个数减1
	arr->cnt--;
	return true;

}
//  访问
bool access_array(Array* arr,size_t index,TYPE* date)
{
	if(index >= arr->cnt) return false;

	*date =arr->ptr[index];
	return true;
}
//  查询
int query_array(Array* arr,TYPE date)
{
	for(int i=0;i<arr->cnt;i++)
		if(arr->ptr[i]==date) return i;
	return -1;
}
//  修改
bool modify_array(Array* arr,size_t index,TYPE date)
{
	if(index >= arr->cnt) return false;
	arr->ptr[index]=date;
	return true;
}
//  排序
void sort_array(Array* arr)
{
	for(int i=0;i<arr->cnt-1;i++)
	{
		for(int j=i+1;j<arr->cnt;j++)
		{
			if(arr->ptr[j]<arr->ptr[i])
			{
				TYPE temp=arr->ptr[j];
				arr->ptr[j]=arr->ptr[i];
				arr->ptr[i]=temp;
			}
		}
	}
}
//  遍历
void show_array(Array* arr)
{
	for(int i=0;i<arr->cnt;i++)
	{
		printf(PH,arr->ptr[i]);
	}
	printf("\n");
}

int main(int argc,const char* argv[])
{
	Array* arr=create_array(10);
	for(int i=0;i<5;i++)
	{
		insert_array(arr,0,i+1);
	}

	insert_array(arr,3,8);
	delete_array(arr,2);
	show_array(arr);

	int num=0;
	if(access_array(arr,5,&num))
		printf("%d\n",num);
	else
		printf("index error\n");

	printf("index=%d\n",query_array(arr,8));

	sort_array(arr);
    show_array(arr);
	clear_array(arr);
	show_array(arr);
	destroy_array(arr);
    arr=NULL;
	return 0;
}
运行的结果
5 4 8 2 1 
index error
index=2
1 2 4 5 8 

二、链式表(链表) 

    数据元素(节点)的数据项:

        数据域:可以是各种类型的若干项数据项

        指针域:指向下一个节点的指针

   

    由若干个节点通过指针域连接起来就形成了链表

    不带头节点的链表:

        定义:第一个节点的数据域存储的是有效数据

        缺点:当插入、删除时可能会改变第一个有效节点,传递的参数需要传递二级指针,实现时需要区分是否是操作第一个有效节点,较为麻烦

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

#define TYPE int

// 设计链表的节点结构 node
typedef struct Node
{
	TYPE data;          //节点的数据域
	struct Node* next;  //节点的指针域
}Node;

// 创建节点
Node* create_node(TYPE data)
{
	//
	Node* node=malloc(sizeof(Node));
	node->data=data;
	node->next=NULL;
	return node;
}

//  头添加
void add_head_list(Node** head,TYPE data)
{
	Node* node=create_node(data);
	node->next=*head;
	*head=node;
}

//  按值删除
bool del_value_list(Node** head,TYPE data)
{
	//  删除第一个值
	if((*head)->data==data)
	{
		Node* temp=*head;
		*head=(*head)->next;
		free(temp);
		return true;
	}
	// 遍历找到待删除节点的前一个节点
	for(Node* n=*head; n->next;n=n->next)
	{
		if(n->next->data==data)
		{
			Node* temp=n->next;
			n->next=temp->next;
			free(temp);
			return true;
		}
	}
	return false;
}

//  遍历链表
void show_list(Node* head)
{
	for(Node* n=head; n; n=n->next)
	{
		printf("%d ",n->data);
	}
	printf("\n");

}

// 访问  第index个位置是哪个值
bool access_list(Node* head, size_t index, TYPE* data)
{
	/*for(int i=0;i<index;i++)
	{
		if(head->next==NULL)
			return false;
		head=head->next;
	}
	*data=head->data;
	return true;*/
	int i=0;
	for(Node* n=head; n;n=n->next,i++)
	{
		if(i==index)
		{
			*data=n->data;
			return true;
		}
	}
	return false;
}

//  排序
void sort_list(Node* head)
{
	for(Node* i=head;i->next ;i=i->next)
	{
		for(Node* j=i->next;j;j=j->next)
		{
			if(j->data<i->data)
			{
				TYPE temp=j->data;
				j->data=i->data;
				i->data=temp;
			}
		}
	}
}

//  按位置删除
bool del_index_list(Node** head,size_t index)
{
	//  删除第一个值
	if(0==index)
	{
		Node* temp=*head;
		*head=temp->next;
		free(temp);
		return true;
	}

	Node* n=*head;
	for(int i=1;n->next;n=n->next,i++)
	{
		if(i==index)
		{
			Node* temp=n->next;
			n->next=temp->next;
			free(temp);
			return true;
		}
	}
	return false;
	/*while(--index)
	{
		n=n->next;
		if(NULL==n) return false;
	}
	if(NULL==n->next) return false;
		Node* temp=n->next;
		n->next=temp->next;
		free(temp);
		return true;
		*/
}

int main(int argc,const char* argv[])
{
	Node* head =create_node(10);
	for(int i=0;i<5;i++)
	{
		add_head_list(&head,i+1);
	}
	show_list(head);
	del_value_list(&head,1);
	show_list(head);

	int num=0;
	if(access_list(head,8,&num))
		printf("num=%d\n",num);
	else 
		printf("error\n");
	sort_list(head);
	show_list(head);
	del_index_list(&head,2);
	show_list(head);
	return 0;
}
运行结果
5 4 3 2 1 10 
5 4 3 2 10 
error
2 3 4 5 10 
2 3 5 10 

    带头节点的链表:

        定义:第一个节点作为头节点,数据域不使用不存储有效数据,它的指针域永远指向链表的第一个有效数据节点,就算链表长度为0,头节点依然存在

        优点:当插入、删除时是不会改变头节点的指向,只需要改变它的next,因此无需传递头节点的二级指针,并且实现时无需区分两种情况

        注意:有效节点的处理必须从头节点的next开始

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

#define TYPE int

// 节点结构
typedef struct Node
{
	TYPE data;          //数据域
	struct Node* next;  //指针域
}Node;

//   创建节点
Node* creat_node(TYPE data)
{
	Node* node=malloc(sizeof(Node));
	node->data=data;
	node->next=NULL;
	return node;
}

//  头添加
void add_head_list(Node* head,TYPE data)
{
	Node* node=creat_node(data);
	node->next=head->next;
	head->next=node;
}

// 尾添加
void add_tail_list(Node* head,TYPE data)
{
	Node* node=creat_node(data);
	while(head->next!=NULL)
		head=head->next;
	head->next=node;
}

//插入 
bool insert_list(Node* head,size_t index,TYPE data)
{
	int i=0;
	for(Node* n=head; n->next ;i++,n=n->next)
	{
		if(i==index)
		{
			Node* node=creat_node(data);
			node->next=n->next;
			n->next=node;
			return true;
		}
	}
	return false;
}

//  按位置删除
bool del_index_list(Node* head,size_t index)
{
	int i=0;
	for(Node* n=head; n ;n=n->next,i++)
	{
		if(i==index)
		{
			Node* temp=n->next;
			n->next=temp->next;
			free(temp);
			return true;
		}
	}
	return false;
}

//  按值删除
bool del_value_list(Node* head,TYPE data)
{
	for(Node* n=head; n->next ;n=n->next)
	{
		if(data==n->next->data)
		{
			Node* temp=n->next;
			n->next=temp->next;
			free(temp);
			return true;
		}
	}
	return false;
}

//  按相同值删除
int del_samevalue_list(Node* head,TYPE data)
{
	int cnt=0;
	Node* n=head;
	while(n->next)
	{
		if(data==n->next->data)
		{
			Node* temp=n->next;
			n->next=temp->next;
			free(temp);
			cnt++;
		}
		else
		{
			n=n->next;
		}
	}
	return cnt;
}


// 修改
int modify_list(Node* head,TYPE old,TYPE data)
{
	int cnt=0;
	Node* n=head->next;
	while(n)
	{
		if(old==n->data)
		{
			n->data=data;
			cnt++;
		}
		n=n->next;
	}
	return cnt;
}

// 访问  第index个位置是哪个值
bool access_list(Node* head, size_t index, TYPE* data)
{
	int i=0;
	for(Node* n=head->next; n ;n=n->next,i++)
	{
		if(i==index)
		{
			*data=n->data;
			return true;
		}
	}
	return false;
}

//  排序
void sort_list(Node* head)
{
	for(Node* i=head->next;i->next;i=i->next)
	{
		for(Node* j=i->next;j;j=j->next)
		{
			if(i->data>j->data)
			{
				TYPE temp=i->data;
				i->data=j->data;
				j->data=temp;
			}
		}
	}
}

//  遍历
void show_list(Node* head)
{
	for(Node* n=head->next; n; n=n->next)
	{
		printf("%d ",n->data);
	}
	printf("\n");

}

int main(int argc,const char* argv[])
{
	//  head指向头节点 不使用为有效节点
	// head->next 指向第一个有效数据节点
	Node* head=creat_node(100);
	for(int i=0;i<10;i++)
	{
		add_head_list(head,i+1);
	}
	show_list(head);
	add_tail_list(head,12);
	insert_list(head,3,12);
	insert_list(head,6,12);
	insert_list(head,1,12);
	insert_list(head,9,12);
	show_list(head);
	del_index_list(head,5);
	show_list(head);
	del_value_list(head,1);
	modify_list(head,12,66);
	show_list(head);
	int num=-1;
	access_list(head,6,&num);
	printf("%d\n",num);
	sort_list(head);
	show_list(head);
	del_samevalue_list(head,66);
	show_list(head);
	return 0;
}
输出结果
10 9 8 7 6 5 4 3 2 1 
10 12 9 8 12 7 6 12 5 12 4 3 2 1 12 
10 12 9 8 12 6 12 5 12 4 3 2 1 12 
10 66 9 8 66 6 66 5 66 4 3 2 66 
66
2 3 4 5 6 8 9 10 66 66 66 66 66 
2 3 4 5 6 8 9 10 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值