从c小白开始自学数据结构——第三天【链表的基本操作】

链表的基本操作:

 

     遍历

     空判断

 

 

     查找

 

 

     清空               

 

     销毁

 

     求长度

 

 

     删除结点

 

 

     插入结点

算法:
                狭义的算法是与数据的存储方式密切相关的
                广义的算法是与数据的存储方式无关的
                泛型: 
                    利用某种达到的效果就是:不同的存储方式,执行的操作是一样的

 

 

 

链表定以后,每一个节点是不用定义其名字的

//链表的一系列基本操作
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>//exit(1);

struct LinkList 
{
	int date;
	struct LinkList * next;
};

struct LinkList * create_LinkList();        //创建链表

void traverse_LinkList (struct LinkList *); //遍历输出

bool is_empty (struct LinkList *);          //判断链表是否为空
 
int lenth_Linklist (struct LinkList *);     //求链表长度

bool insert_LinkList (struct LinkList *, int pos, int);    //插入

bool delete_LinkList (struct LinkList *, int pos, int*);   //删除

void sort_LinkList (struct LinkList *);     //排序

int main ()
{
    int pos, val;
	
	struct LinkList * pHead = create_LinkList();
    traverse_LinkList (pHead);

	int len = lenth_Linklist (pHead);
	printf ("链表长度为%d\n", len);
     
	printf("插入的位置:");
	scanf("%d", &pos);
	printf("插入的数字:");
    scanf("%d", &val);
	insert_LinkList (pHead, pos, val);
    traverse_LinkList (pHead);

	int depos, deval;
	printf("删除的位置:");
	scanf("%d", &depos);
	delete_LinkList (pHead, depos, &deval);
	traverse_LinkList (pHead);
    printf ("删除结点的值为:%d\n", deval);    

	return 0;
}

struct LinkList * create_LinkList()
{
	int a, b, val;
	//创建头结点
	struct LinkList * pHead = (struct LinkList *)malloc(sizeof(struct LinkList) );
	if (pHead == 0)
	{
		printf ("生成失败。");
		exit(1);
	}
	else
		pHead->date = NULL;//头结点的数据域为空
	    
    struct LinkList * pTail = pHead;//pTail,pHead都指向头结点,
    pTail->next = NULL;             //清空头结点指针域,pTail->next和pHead->next是等价的,指针域清空了后用pTail->next = 写入新的指针域,写入后,就保存在pHead->next里面
		                            //浪费时间的原因:最开始的时候,我一直在思考,怎么让pHead指向下一个结点,我觉得pTail->next指向的下一个节点和pHead->next似乎没啥关系
	                                      //或者说我那时想的pHead->next=pTail->next->next我还想过弄一个首指针加俩if判断,好在想通了,蛮干不如多思考

	printf ("请输入你要生成链表成员的个数。");
	scanf ("%d", &a);
    //建立链表
	for (b=0;b<a;b++)
	{
        printf ("请输入链表第%d个成员的值:", b+1);
		scanf ("%d", &val);
        //新结点
        struct LinkList * pNew = (struct LinkList *)malloc(sizeof(struct LinkList) );
        if (pNew == 0)
		{
	    	printf ("生成失败。");
	    	exit(1);
		}
        pNew->date = val;

		pTail->next = pNew;//头结点指针域指向pNew
		pTail = pNew;      //不断循环后,向后赋值
	}   
	
	pTail->next = NULL;    //放在for循环外面,给尾结点,放在里面会执行很多次,但是也是正确的
	
	return pHead;
}

void traverse_LinkList (struct LinkList * pHead)
{
	int i=1;
	struct LinkList * p = pHead->next;
	while(p != NULL)//这里是不为空,要等到循环到尾结点才为空,循环终止
	{
		printf ("链表第%d个数为:%d\n", i, p->date);
		p = p->next;
		i++;
	}
    return;
}

bool is_empty (struct LinkList * pHead)
{
	if (pHead->next == NULL)   //(pHead->next->date==NULL)不行,万一首结点的数据域就是NULL。。。头结点的指针域为空,就只有一个头结点,是空链表
		return true;
		//printf ("链表为空。");
    else
		return false;
}

int lenth_Linklist (struct LinkList * pHead)
{
	struct LinkList * p = pHead->next;
	int len = 0;
	//if ( bool is_empty(pHead) ==false)多余了,链表为空就是长度为0
    while (p!=NULL)
	{
		len++;
		p = p->next;//这里p = p->next,p要是等于pHead->next,那么p的值会一直刷新到pHead->next,循环不会完成,一直循环,就显示不出printf ("链表长度为%d", len);
	}
	return len;
}

bool insert_LinkList (struct LinkList *pHead, int pos, int val)
{
	int i=1;//i不能等于0,等于0就是从0开始遍历,即i=0 ++,要遍历到pos上去
	//判断链表是否为空,不需要这个步骤,为空就在头指针后面插一个
	struct LinkList *p = pHead;
	struct LinkList *t;
	while (p->next&& i<pos)//遍历寻找第pos-1个结点,p->next和p是一个效果,我也不知道为什么,想不通。我曹,他是&&循环才截止,达到一个过后还要达到另一个,都会遍历到p->next==NULL才完,所以两个是一样的。
	{
		p=p->next;
		i++;
	}
	printf ("i=%d\n",i);
	if (p == NULL || i>pos)//判断插入的位置在不在链表内,此处是p不是p->next,若是p->next则尾插的时候指向了最后一个的最后一个必然不存在的,尾插插不了
	{
		printf ("链表没有第%d个结点\n", pos);
		return false;
	}
    struct LinkList * pNew = (struct LinkList *)malloc(sizeof(struct LinkList));//创建结点
	pNew->date = val;
    
	t=p->next;
	p->next = pNew;
	pNew->next=t;//插入:t=p->next,p->next = pNew->next,pNew->next=t;
	return true;

}

bool delete_LinkList (struct LinkList * pHead, int pos, int * val)
{
	int i=1;
    struct LinkList *p = pHead;
	struct LinkList *q;
	while (p && i < pos )//是while (p==NULL && i < pos )这里错了,后面那个//p=p->next->next ;也是错的,为什么?
	{
		p=p->next ;
		i++;
	}
	if (p == NULL || i>pos)
	{
		printf ("链表没有第%d个结点\n", pos);
		return false;
	}
	//p=p->next->next ;
	q=p->next;//p->next被删除元素的
	p->next=q->next;
	*val = q->date;
    free(q);
	return true;
}

排序有点难啊,不太搞得懂,看是今天晚上还是明天来排。

 

嗯,首行缩进三个字符都是异端,就是这样

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值