C语言单链表

链表是通过一组任意的存储单元来存储线性表中的数据元素

定义节点如下:(语言是标准C语言)

#include <stdio.h>
#include <stdlib.h>
#define ERROR -1;//错误
#define TRUE 0;//正确
typedef struct node{

    ElemeteType data;//数据域
    
    struct node next;//指针域

}LNode,*LinkList;

单链表的基本操作

建立单链表(头插法),时间复杂度:O(n)

/**
  *   头插法
  */
LinkList Create_LinkList1(){
	LinkList H=(LinkList) malloc(sizeof(LNode));//生成头结点
	H->next=NULL;//建立一个空表
	LNode *s;
	int x;     //设数据元素的类型为int 
	scanf("%d",&x);
	while(x!=-1){
		s=(LinkList)malloc(sizeof(LNode));
		s->data=x;
		s->next=H->next;
		H->next=s;
		scanf("%d",&x);
	}
	return H;
}

建立单链表(尾插法),时间复杂度:O(n)

/**
  *   尾插法
  */
LinkList Create_LinkList2(){

	LinkList H=(LinkList)malloc(sizeof(LNode));//生成头结点
	H->next=NULL;
	LNode *s,*t;
	t=H;
	int x;     //设数据元素的类型为int 
	scanf("%d",&x);
	while(x!=-1){
		s=(LinkList)malloc(sizeof(LNode));
		s->data=x;
		s->next=t->next;
		t->next=s;
		t=s;  //t指向新的尾节点
		scanf("%d",&x);
	}
	return H;
}

求表长,时间复杂度O(n) 

/**
 * 求表长
 */
int Length_LinkList(LinkList H){

	LNode *p=H;
	int j=0;
	while(p->next!=null){
		p=p->next;
		j++;
	}
	return j;

}

查找操作(按序号查找),时间复杂度:O(n)

/**
 * 查找操作,按序号查找
 */
LinkList Get_LinkList(LinkList H,int k){

	LNode *p=H;
	int j=0;
	while(p->next!=NULL&&j<k){
		p=p->next;
		j++;
	}
	if(j==k){
		return p;
	}else{
		return NULL;
	}
}

查找操作(按值查找),时间复杂度:O(n)

/**
 * 查找操作,按值x查找
 */
LNode *Locate_LinkList(LinkList H,int x){
	LNode *p=H->next;
	while(p!=NULL&&p->data!=x){
		p=p->next;
	}
	return p;
}

单链表的插入操作,插入第i个位置,时间复杂度:O(n)

/**
 * 插入操作 时间复杂度 O(n)
 */
int Insert_LinkList(LinkList H,int i,int x){
	//在单链表H的第i个位置插入值为x的元素
	LNode *p,*s;
	p=Get_LinkList(H,i-1);//查找第i-1个节点(插入的位置,我们得知道这个节点的前驱节点)
	if(p=NULL){
		printf("插入的位置i错");
		return ERROR;
	}else{
		s=(LinkList)malloc(sizeof(LNode));//申请新节点
		s->data=x;
		s->next=p->next; //新节点插入在第i-1个节点后面
		p->next=s;
		return TRUE;
	}
}

单链表的删除操作,时间复杂度O(n)

/**
 * 删除节点 删除第i个节点
 */
int Del_LinkList(LinkList H,int i){
	LinkList p,q;
	p=Get_LinkList(H,i-1);//查找第i-1个节点
	if(p==NULL){
		printf("第i-1个节点不存在");
		return ERROR;
	}else{
		q=p->next;  //指向第i个节点
		p->next=q->next;  //从链表中删除
		free(q);  //释放*q
		return TRUE;
	}	
}

单链表的倒置,时间复杂度O(n)

思路:依次取出原链表中的每个节点,将其作为第一个节点插入新链表中,指针p用来指向当前节点,p为空时结束

/**
 * 单链表的倒置
 */
void Reverse(LinkList H){
	
	LNode *p,*q;
	p=H->next;//指向第一个数据元素(别忘了,我们之前是定义的带表头的哦)
	H->next=NULL;//把头节点卸下来
	while(p){
		q=p;
		p=p->next;//p指针一直指在旧链表上,直到"指"到最后为空
		//将当前节点插到头结点的后面,想不来的话回忆一下建立链表头插法你就了然了,
		//注意第一次插入的时候H->next是空的,也就是NULL
		q->next=H->next;
		H->next=q;
	}
}

如果大家还有点想不来倒置,我下面有个图解释了怎么倒置

看的顺序:黑色字体->红色字体->绿色字体

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值