数据结构笔记一(20120818)

数据结构笔记一(20120818)

1.顺序表

逻辑(数值)上相邻,地址上连续,是顺序结构。

添加节点和删除节点,结果就是后面所有的数进行前移或往后移动;

2.链表

链表的创建,增加,排序和删除节点;

单链表:逻辑(数值)上相邻,地址上不一定连续;

用结构体来表示,一个数据和其地址,为一个节点;

typedef struct node

{

        struct stu s;

        struct node *next;   //可以不断的指向链表中的下一个数据地址;

}NODE;

创建链表:

定义指针后,先进行初始化,将指针赋值NULL或者有效的值,应用的时候,需要进行对指针进行判断。

在创建链表的函数creatlist()可以修改head的值,只有将地址传过去;或者不传参数,只将返回值返回到head

一般查找用顺序表,插入和删除用链表,在这两种情况下效率高;

如果用定义的变量或对象的方式进行分配空间,结果是分配空间到堆,用malloc就是在堆区,需要进行free的释放。

 

**********************************代码及其分析**********************************

  

/*
 *wuxiuwen 
 *链表的创建,增加、删除节点
 *
 */
#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
	int data;
	struct node *next;
}NODE;

//函数的声明
void Creatlist(NODE **);
void  output(NODE const *);
void freelist(NODE **);
NODE *getnode();
NODE *insertlist(NODE *head,int pos);
NODE *insertlist_node(NODE *head,NODE *pnew);
NODE *removenode(NODE *head,NODE *pnew);

//函数的声明的结束

int main()
{	
	NODE *head = NULL;
	int m;
	NODE *pnew=NULL;
		
	Creatlist(&head);  
  /*创建链表,链表的头部是head,因为要对链表操作,所以取其地址进行操作*/
	output(head);
  //输出链表	
  head = insertlist(head,5);      //插入到链表中的第五个位置
  output(head);
	pnew = getnode();   //获取一个节点,用来进行增加和删除操作
	head = insertlist_node(head,pnew);//插入节点pnew到有序的链表中,形成有序的链表
	output(head);
	head = removenode(head,pnew);  //删除head链表中的与pnew有匹配的节点
	output(head);
	freelist(&head);   //释放空间
	

}
/*释放申请链表时用malloc申请的堆的空间
*/
void freelist(NODE **phead)  
/*可以对当前的链表进行操作,传递的进来的是指向头链表的指针*/
{
	NODE *pp=NULL;
	while(*phead !=NULL)  //用循环,释放每一个申请的堆的空间
	{
		pp=*phead;
		*phead = (*phead)->next;    //这两句就是遍历了整个链表
		free(pp);
	}	
}
NODE *insertlist(NODE *head,int pos)   //插入到链表中的第POS个位置
{
	NODE *pnew=getnode();    //获取到一个节点,将这个节点插入到head中的第POS个
  /*思路是思考几种情况,如果是空链表,如果不是空链表的话,插入到第一个位置,或	者是插入到不是第一个位置*/
	NODE *p=NULL;
	int i;

	if(head ==NULL)    
	{
		head=pnew;
		return head;
	}
	if(pos ==1)
	{
		p->next = head;
		head=p;
		return head;
	}
	i = pos -2;
	p = head;
	while(i !=0 && p->next !=NULL)  //这个循环用来定位到第POS前的以为的NODE
  //如果这个位置超出这个链表的长度,直接放到最后
	{
		p = p->next;           //p =head,从开始头出开始遍历
		--i;
	}
	pnew ->next = p->next;     
  //将这个心的节点插入到第POS的位置上,因为当前的p->next就是要插入的位置*/
	p->next = pnew;
	return head;    //返回修改后的链表的头
}	

void output(NODE const *phead)  //输入链表,主要是用来打印,做验证用
{
	NODE *pp =NULL;
	pp = (NODE *)phead;            
/*强制类型转换,传递进来的是一个const的值,不会修改到原来的链表的任何的值;*/
	while(pp!=NULL)
	{
		printf("%d\t",pp->data);    //遍历输出
		pp = pp->next;
	}
	printf("\n");
	
}

NODE *getnode()             /*利用动态分配空间来进行获取节点*/
{
	NODE *pnew;
	pnew =(NODE *)malloc(sizeof(NODE));
	if(pnew == NULL)
	{
		exit(1);
	}
	scanf("%d",&(pnew->data));
	pnew->next=NULL;
	return pnew;
}
void Creatlist(NODE **phead)   /* 创建链表, */
/*可以对当前的链表进行操作,传递的进来的是指向头链表的指针*/
{
	NODE *pnew=NULL;
    NODE *pend =NULL;
	
  pnew =getnode();
	while(pnew->data!=0)
	{
		if(*phead == NULL)  //初始化链表的第一个节点
		{
			*phead  =  pnew;
			 pend   =  pnew;
		}
		else 
		{
			pend->next = pnew;   //进行从第二个节点的定位和赋值
			pend = pnew;
		//	pnew->next = *phead;
		//	*phead = pnew;
		}
		pnew = getnode();  //对下面的节点进行获取
	}
	free(pnew);  //释放最后一个分配的空间
}

NODE *insertlist_node(NODE *head,NODE *pnew)
/*插入节点pnew到有序的链表中,形成有序的链表*/
{ 
	int i;
	NODE *p = head;
	if(p == NULL)
	{
		head = pnew;
		return head;
	}
	if((p == head) && (p->data) >= (pnew->data))  //程序的健壮性(p == head) 
	{
		pnew->next = head;   //插入到第一个节点上
		head = pnew;
		return head;
	}
  /*根据DATA数值的判断,定位到p->next的值为要插入的值,然后进行节点的插入*/
	while(p->next != NULL)
	{
		if((p->data) < (pnew->data) && (p->next->data) >= (pnew->data))
		{
			break;
		}
		p = p->next;
	}
	pnew ->next = p->next;  
  /*根据DATA数值的判断,定位到p->next的值为要插入的值,然后进行节点的插入*/
	p->next = pnew;
	return head;
}
NODE *removenode(NODE *head,NODE *pnew)
{
	NODE *pp=NULL;
	pp =head;
	if(head == pnew)
	{	
		head =head->next;
		return head;
	}
	while(pp->next !=NULL)
	{
		if(pp->next !=pnew)
		{
			pp= pp->next;
		}
		else
		{
			pp->next = pp->next->next;
			free(pp->next);
			return head;
		}
		if(pp->next ==NULL)
		{
			printf("here is error,please input other node!\n");
		}
	}
}



*********************************执行结果****************************

[root@localhost 20120818]# ./a.out
2 4 6 7 0
2 4 6 7 
8
2 4 6 7 8 
5
2 4 5 6 7 8 
2 4 0 7 8 
[root@localhost 20120818]#

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值