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;
}
}
如果大家还有点想不来倒置,我下面有个图解释了怎么倒置
看的顺序:黑色字体->红色字体->绿色字体