12学习总结

        这段时间主要学习了c语言高级知识,和数据结构的部分。在学习完c语言指针函数等知识过后,进行了数据结构部分的学习,数据结构主要学习了链表,栈结构,队列,树和二叉树,哈希表,和一下排序算法。

        其中数据结构中的链表部分最为重要,链表是一种可以利用零散空间的数据结构,它利用一个next指针指向下一个节点,我们可以利用这一点进行链表的创建,修改,增减,删除等操作

        栈这种数据结构在日常使用的并不多,主要用于系统中,一个栈有栈顶和栈底,数据只可以从栈顶进,栈顶出,所以满足先进后出原则

        队列的特点

特点:先进先出, 后进后出

实现:  顺序结构    链式结构


概念:  队头   队尾

ps:  不允许在中间做插入或者删除的操作

        二叉树带有一个左孩子和一个右孩子,我们学习了先序遍历,中序遍历,和后序遍历

        

不带头结点的单链表创建

//创建新的节点
struct node* create_node()
{
	struct node *pnew  = NULL;
	pnew = (struct node*)malloc(sizeof(struct node));
	if(NULL == pnew)
	{
		printf("malloc  error!%s, %d\n", __FILE__,__LINE__);
		exit(-1);
	}
	pnew->next = NULL;
	return pnew;
}
//尾插法创建链表
struct node* create_list()
{
	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__);
			break;
		}
		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;
}

不带头结点的单链表删除

//ps:删除操作重点考虑:  头删和其他位置
void list_del_by_index(struct node **phead, int index)
{
	//入参检查
	if(phead == NULL)
	{
		return ;
	}
	if(*phead == NULL)
	{
		return ;
	}

	int len = list_len(*phead);
	if(index<1 ||  index>len)
	{
		return ;
	}
	//正确流程
#if  0
	(1)保存删除节点地址
		(2)将删除节点从链表中移除
		(3)释放内存
#endif
		struct node *pdel = NULL;
	if(1 == index)
	{
		pdel = *phead;
		*phead = (*phead)->next;
		free(pdel);
	}
	else
	{
		struct node *psearch = list_search_by_index(*phead, index-1);
		pdel = psearch->next;
		psearch->next = pdel->next;
		free(pdel);
	}

	return ;

}

不带头结点的单链表升序

//(1)从旧链表中找出最大值
struct node*find_max_from_oldlist(struct node*head)
{
	struct node *pmax = head;
	struct node *p = head;
	
	while(p!=NULL)
	{
		if(p->data > pmax->data)
		{
			pmax = p;
		}
		p = p->next;
	}
	return pmax;
}

//(2)将最大值从旧链表中移下来
struct node* remove_max_from_oldlist(struct node*head, struct node*pmax)
{

	if(pmax == head) 
	{
		head = head->next;
	}
	else
	{
		struct node *p = head;
        while(p->next != pmax)
		{
			p = p->next;
		}

		p->next = pmax->next;
	}
	pmax->next = NULL;
	return head;
}

//(3)将最大值通过头插法加入新的链表
struct node* add_newlist(struct node*head, struct node *pmax)
{
	pmax->next = head;
	head = pmax;
	return head;
}


//链表的升序排序
struct node*list_sort(struct node *head)
{
	struct node *new_head = NULL;
	struct node *pmax = NULL;

	while(head!=NULL)
	{
		//(1)从旧链表中找出最大值
		pmax = find_max_from_oldlist(head);
		//(2)将最大值从旧链表中移下来
		head = remove_max_from_oldlist(head, pmax);
		//(3)将最大值通过头插法加入新的链表
		new_head = add_newlist(new_head, pmax);
	}
	return new_head;
}

带头结点的链表最重要的就是创建一个头结点,保存链表的基本信息,在这个头结点的后面进行,增删改查等操作

带头结点的链表添加

//头插法创建链表
void create_list(struct node *head)
{
	struct node *pnew = NULL;
	char ch;
	printf("是否创建链表?");
	scanf("%c", &ch);
	while(getchar()!='\n');

	while(ch == 'y' || ch== 'Y')
	{
		//1、创建新的节点,并赋值
		pnew = create_node();
		printf("请输入学号:");
		scanf("%d", &pnew->num);
		while(getchar()!='\n');
		printf("请输入姓名:");
		scanf("%s", pnew->name);
		while(getchar()!='\n');

	   //2、加入链表
#if   0
	   if(head->next == NULL) //空链表
	   {
		   head->next = pnew;
	   }
	   else  //头插法加入链表
	   {
		   pnew->next = head->next;
		   head->next = pnew;
	   }
#endif
	pnew->next = head->next;
	head->next = pnew;

       printf("是否继续?");
	   scanf("%c", &ch);
	   while(getchar()!='\n');
	}

	return ;
}

带头结点的链表查找,插入

//查找操作
struct node *list_search_by_num(struct node *head, int num)
{
	struct node *p = head->next;
	while(p!=NULL)
	{
		if(p->num == num)
		{
			return p;
		}
		p = p->next;
	}
	return p;
}



//插入操作: 插入到指定学号的前面
//  ps:不管插入到什么位置,都是找插入位置的前一个节点
void list_insert_by_num(struct node *head, int num, struct node *pnew)
{
	struct node *psearch = NULL;

	psearch = list_search_by_num(head, num);
	if(NULL == psearch)
	{
		printf("插入失败,学号%d不存在!\n", num);
		return ;
	}

	struct node *p = head;
	while(p->next != psearch)
	{
		p = p->next;
	}

	pnew->next = psearch;
	p->next = pnew;
	return ;
}

带头结点的链表删除

//删除操作:
//不管删除哪一个节点, 都是找前一个节点,  让前一个节点的next保存删除节点下一个节点的地址
void list_del_by_num(struct node *head, int num)
{
	struct node *psearch = NULL;

	psearch = list_search_by_num(head, num);
	if(NULL == psearch)
	{
		printf("删除失败,学号%d不存在!\n", num);
		return ;
	}

	struct node *p = head;
	while(p->next != psearch)
	{
		p = p->next;
	}

	p->next = psearch->next;
	free(psearch);
	return ;

}

双向链表就是有一个指向后面的next指针,还有一个指向前面的pre指针,可以更加方便的进行增删改查等操作

双向链表的添加

void create_list(struct node *head)
{
	struct node *pnew = NULL;
	char ch;

	printf("是否创建链表?");
	scanf("%c", &ch);
	while(getchar()!='\n');

	while(ch=='Y'||ch=='y')

	
	{
		//1、创建新的节点,并且赋值
		pnew = create_node();
		printf("请输入学号:");
		scanf("%d", &pnew->num);
		while(getchar()!='\n');
		printf("请输入姓名:");
		scanf("%s", pnew->name);
		while(getchar()!='\n');

		//2、加入链表
		if(head->next == NULL) //空链表
		{
			head->next = pnew;
			pnew->pre = head;
		}
		else  //非空链表,头插法
		{
			pnew->next = head->next;
			head->next->pre = pnew;

			head->next = pnew;
			pnew->pre = head;
		}

		printf("是否继续?");
		scanf("%c", &ch);
		while(getchar()!='\n');
	}
	return ;
}

双向链表的查找

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值