数据结构学习总结

1.单链表

        建立单链表:

        (1)创建节点:

struct node*create_node()
{
	struct node *pnew = NULL;
	pnew = (struct node*)malloc(sizeof(struct node));
	if(pnew==NULL)
	{
		printf("malloc error!\n");
		exit(-1);
	}
	pnew->next = NULL;
	return pnew;

}

(2)头插法: 将新节点从头插入链表

//头插法创建链表
struct node*create_list_by_head()
{
	struct node *head = NULL, *pnew = NULL;

	int x;
	scanf("%d", &x);
	while(getchar()!='\n');

	while(x)
	{
		//1、创建新的节点,并且赋值
		pnew = (struct node*)malloc(sizeof(struct node));
		if(NULL == pnew)
		{
			printf("malloc error!%s, %d\n", __FILE__, __LINE__ );
			exit(-1);
		}
		pnew->data = x;
		pnew->next = NULL;

		//2、加入链表

		pnew->next = head;
		head = pnew;


		scanf("%d", &x);
		while(getchar()!='\n');
	}
	return head;
}

                         尾插法: 将新节点从尾部插入链表

//尾插法创建链表
struct node *create_list_by_tail()
{
	struct node* head = NULL; //头指针, 保存第一个节点的地址
	struct node* pnew = NULL; //保存新的节点地址
	struct node* tail = NULL; //保存最后一个节点的地址

	int x;
	scanf("%d", &x);
	while(getchar()!='\n');

	while(x)
	{
		//1、创建新的节点, 并初始化每一个成员
		pnew = (struct node*)malloc(sizeof(struct node));
		if(NULL == pnew)
		{
			printf("malloc error!%s, %d\n", __FILE__, __LINE__ );
			exit(-1);
		}

		pnew->data = x;
		pnew->next = NULL;


		//2、加入链表
		if(NULL == head) //空链表
		{
			head = pnew;
			tail = pnew;
		}
		else // 非空链表
		{
			tail->next = pnew;
			tail = pnew;
		}

		scanf("%d", &x);
		while(getchar()!='\n');
	}

	return head;
}

        (3)遍历链表:声明一个指针p,从头结点指向的第一个结点开始,如果p不为空,那么就输出当前结点的值,并将p指向下一个结点,直到遍历到最后一个结点为止。

//遍历链表
void  show_list(struct node *head)
{
	if(NULL == head)
	{
		printf("空链表!\n");
	}
	else
	{
		struct node *p = head;
		while(p != NULL)
		{
			printf("[%d|%p]-->", p->data, p->next);
			p = p->next;
		}
		printf("\n");
	}
	return ;
}

        (4)删除链表:先检查删除位置的合法性,然后从头开始遍历,找到表中的第 i-1 个结点,即被删除结点的前驱结点*psearch,被删除结点为*pdel,修改*pdel的指针域,将其指向*psearch的下一个结点,最后再释放结点*pdel的存储空间。

struct node*list_del_by_index(struct node *head, int index)
{
	//入参检查
	if(head == NULL)
	{
		return head;
	}
    int len = list_len(head);
	if(index<1 || index>len)
	{
		return head;
	}

	//正确流程
	//删除操作的步骤:
	//(1) 保存删除节点的地址
	//(2) 将节点从链表中移除
	//(3) 释放内存
	
	struct node *pdel = NULL;
	if(1 == index) //头删
	{
		pdel = head;
		head = head->next;
	}
	else //中间删除或者  尾部删除
	{
		//查找删除节点
        pdel = list_search_by_index(head, index);

		//查找删除节点的前一个节点
        struct node *psearch  = list_search_by_index(head, index-1);
	
		psearch->next = pdel->next;
	}
	free(pdel);
	return head;
}

        (5)插入新节点:从表头开始遍历,查找第 i-1个结点,即插入位置的前驱结点为psearch,然后令新结点pnew的指针域指向pnew的后继结点,再令结点psearch的指针域指向新结点*pnew。

struct node*list_insert_by_index(struct  node *head, int index,  int data)
{
	//入参检查
	int len  = list_len(head);


#if   0
    if(index<1 || index>len+1)
	{
		printf("param error!\n");
		return head;
	}
#endif

	if(index < 1)
	{
		index = 1;
	}

	if(index > len+1)
	{
		index = len+1;
	}

	//正确的流程
	struct node *pnew = create_node();
	pnew->data = data;


	if(index == 1)
	{
		pnew->next = head;
		head = pnew;
	}
	else   //中间  或者 尾部追加
	{
		//查找index节点的前一个节点
		struct node *psearch = NULL;
		psearch = list_search_by_index(head, index-1);
		
		//将新的节点加入链表
		pnew->next =  psearch->next;
		psearch->next = pnew;
	}
	return head;
}

        (6)查找链表节点:从单链表的第一个结点开始,顺着指针域逐个往下搜索,直到找到第 i 个结点为止,否则返回最后一个结点的指针域NULL

struct node *list_search_by_index(struct node *head, int  index)
{
	//入参检查
	if(NULL == head)
	{
		return NULL;
	}
	int len  = list_len(head);
	if(index<1 || index>len)
	{
		printf("param  error!%s, %d\n", __FILE__,__LINE__);
		return NULL;
	}

	//正确流程
	struct node *p = head;
	for(int i=1; i<index; i ++)
	{
		p = p->next;
	}
	return p;
}

2.双向链表

        可以从头遍历到尾,也可以从尾遍历到头

        每次在插入或删除某个节点时, 需要处理四个节点的引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值