单链表的插入,删除(C语言)(链式)Version2

#小菜鸡的数据结构学习之路
#仿照《大话数据结构》
#IDE VC++6.0

#include <stdio.h>
#include <string>
#include <windows.h>
#include <time.h>
#include <graphics.h>
typedef struct Node
{
	int data;
	struct Node *next;
}node;
typedef struct Node *LinkList;    //LinkList 此时相当于一个结构体指针 后面可以直接用 

/*----------固定位置的不同表达(	p=(*L)->next)----------------*/
void InsertLinkList(LinkList *L,int i,int element)   //!!!!一定要搞清楚自己心里的 结点位置排布 结点0在哪个位置
{
	int j=1;
	LinkList p,s,temp;
	p=(*L)->next;               //(p=(*L)->next)这样比较容易处理移动距离的问题 无论是 i= 0 1 ...
    if(p && (i==0))
	{
        temp=(LinkList)malloc(sizeof(node));
		temp->data=element;
		temp->next=(*L)->next;
		(*L)->next=temp;
	}
	
	while(p && j<i )         //比如i=2 (1<2) p-->第0个结点位置 
	{
		p=p->next;
		++j;
	}
	if(!p || j>i)
		return ;
    s=(LinkList)malloc(sizeof(node));
	s->data=element;
	s->next=p->next;
	p->next=s;
	
}

/*-------固定位置的不同表达(	p=*L)-------*/
void InsertLinkList1(LinkList *L,int i,int element)   //!!!!一定要搞清楚自己心里的 结点位置排布 0在哪个位置
{
	int j=0;                    //上面哪个是j=1 此处细品 建议画图理清思路
	LinkList p,s,temp;
	p=*L;                      // (p=*L)对比上面的(p=(*L->next)
    	
	while(p && j<i)      //比如i=2 
	{
		p=p->next;
		++j;
	}
	if(!p || j>i)
		return ;
    s=(LinkList)malloc(sizeof(node));
	s->data=element;
	s->next=p->next;
	p->next=s;
	
}

//删除的时候记得判断条件的选取 (p->next)
/*----------头删除-------------------------*/
void DeleteHead(LinkList *L,int *e)
{
	LinkList p=(*L)->next;
	if(p == NULL)
	{
		printf("The List is empty!\n");
		return;
	}
	(*L)->next=p->next;
	free(p);
}

/*--------------尾删除----------------------*/
void DeleteTail(LinkList *L,int *e)  //这步遇到的问题是 太心急了 直接找到是要删除的
{                                    //这样的话 要删除的前一个的->next没有了明确的指向
	LinkList p=(*L)->next;           //所以还是先找前一个
	LinkList q=NULL;
	if(p == NULL)
	{
		printf("The List is empty!\n");
		return;
	}
	while(p->next)                  //q保留的是要找的前一个 p是要删除的
	{
		q=p;                       //注意此时的判断条件
		p=p->next;
	}
	*e=p->data;
	if(p == ((*L)->next))        //处理只有一个结点的情况
		(*L)->next=NULL;
	free(p);
	q->next=NULL;
}

/*-----------固定删除位置------------------*/
void DeleteFixLocal(LinkList *L,int i,int* element)  
{
	int j=0;                    //上面哪个是j=1 此处细品 建议画图理清思路
	LinkList p,s,temp;
	p=*L;                      
    	
	while(p && j<i)      //比如i=2 
	{
		p=p->next;
		++j;
	}
	if(!p || j>i)
		return ;
	
	s=p->next;                    //这里已经包含了 i=0  的情况
	*element=s->data;
	p->next=s->next;
	free(s);
  
}

/*---------打印链表元素----------------*/
void Print(LinkList L)
{
	LinkList p;
	p=L->next;

	if(p==NULL)
		printf("空链表");
	while(p)
	{
		printf("%2d \t",p->data);
		p=p->next;
	}
	printf("\n");
	
}

/*------------------头插法多个----------*/
void CreateListHead(LinkList *L,int n)
{
	int count=10;
	srand(time(0));
	LinkList p;
	*L=(LinkList)malloc(sizeof(node)); //记住头结点的指针的指针 用二级指针的值(*L)即一级指针(LinkList)开辟单元
	(*L)->next=NULL;
	for(int i=0;i<n;i++)
	{
    	p=(LinkList)malloc(sizeof(node));
		//p->data=rand()%100+1;
		p->data=count;
		p->next=(*L)->next;
		(*L)->next=p;
		++count;
	}
}

/*----------单独头插一个------------------*/
void CreateListHead1(LinkList *L,int value)
{
	LinkList p;
	p=(LinkList)malloc(sizeof(node));
	//p->data=rand()%100+1;
    p->data=value;
	p->next=(*L)->next;
	(*L)->next=p;
}

/*---------------尾插--------------*/
void Tail(LinkList *L,int n)                       //自己想的
{
	int count=10;
	*L=(LinkList)malloc(sizeof(node));
	(*L)->next=NULL;
	LinkList p,s,rear;
	p=(*L)->next;
	for(int i=0;i<n;i++)
	{
		if(i==0)                           //如果插入的位置是第一个
		{	
			p=(LinkList)malloc(sizeof(node));
		    p->data=count;
		    p->next=(*L)->next;
			(*L)->next=p;
			rear=p;
			++count;
		}
		else                             //如果插入的位置是其他任意
		{
			s=(LinkList)malloc(sizeof(node));
			s->data=count;
			rear->next=s;
			rear=s;                         //q记录即将要新插入的结点前的那个结点
			++count;
		}
		
	}

}
/*-----------------尾插--------------------*/
void CreateListTail(LinkList *L,int n)     //别人的
{
	int count=10;
	*L=(LinkList)malloc(sizeof(node));
	(*L)->next=NULL;
	LinkList p,q;
	q=*L;                                    //q用来记录前一个结点位置
	for(int i=0;i<n;i++)
	{
		p=(LinkList)malloc(sizeof(node));
		p->data=count;
		p->next=(*L)->next;
		q->next=p;
		q=p;
	    ++count;
	}
	q->next=NULL;                           //记得来处理最后的情况
}

void ClearList(LinkList *L)
{
	LinkList p,q;
	p=(*L)->next;
	while(p->next)
	{
		q=p->next;
		free(p);
		p=q;
	}
	free(p);
	(*L)->next=NULL;
}

void main()
{
   /*
   initgraph(640,640);
   IMAGE img;
   loadimage(&img,_T("C://Users//木歌//Pictures//001CG.bmp"));
   putimage (100,100,&img);
   Sleep(5000);
   */

   int k=3;
   LinkList L;
   
   //CreateListHead(&L,k);
   //Tail(&L,k);
   CreateListTail(&L,k);
   InsertLinkList(&L,0,3);
   InsertLinkList(&L,1,4); 
   //InsertLinkList(&L,2,5);
   InsertLinkList1(&L,2,5);
   InsertLinkList1(&L,3,6);
   CreateListHead1(&L,100);
   Print(L);

   DeleteHead(&L,&k);
   Print(L);
   DeleteTail(&L,&k);
   Print(L);
   
   DeleteFixLocal(&L,2,&k);
   Print(L);
   DeleteFixLocal(&L,1,&k);
   Print(L);
   DeleteFixLocal(&L,0,&k);
   Print(L);

   ClearList(&L);
   Print(L);
   closegraph();
   printf("\n");
   
}

#相对上一个版本 1.增加了删除函数 2.改进了之前的插入函数
#删除的时候,注意寻找要删除的前一个,可能如果没有打印函数,就不会发现这样一个问题,如果直接删除 ,要删除的那个,它直面的那个的next指针便没有了具体的指向(可能会有个随机值),但是如果先找到前一个,再继续删除 并给前一个的next指针赋值为NULL,便可以很完美。
#插入函数,之前的版本我把i=0 ,i=1的情况单独拿出来,是因为当时还没有明白 代码的进一步含义(当然之前的代码可以实现相关功能),属于考虑不当,多做的情况,想清楚联系的时候,在修改,便会比较清爽。(这个情况也是在我补充删除函数的时候进行的尝试)
#在此,在强调一点 j=0,p=(*L)
和 j=1,p=(*L)->next 的情况 需要多思考,可以自己画图辅助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值