数据结构c语言链表的基本操作,数据结构 - 单链表的基本操作 (C语言)

本文详细介绍了单链表的创建、计算表长、按值和序号查找、插入、删除、逆置以及删除重复元素等操作。通过头插法和尾插法创建单链表,并提供了相应的C语言实现。强调了单链表附加头结点的好处以及在操作中需要注意的细节。
摘要由CSDN通过智能技术生成

单链表:一组任意存储单元组成的线性表. 单链表这块也没有什么难点,都是一些基本操作。但是应该注意以下几点:

(1)  :单链表一般附加头结点,这样做的好处是:初始化单链表后头指针不需要再改动.

(2)  :头结点的数据域一般不存储数据 或者 存储标题,表长等信息.

而单链表的存储结构一般如下:

typedef int ElemType;

typedef struct node

{

ElemType data;

struct node *next;

}LNode,*LinkList;

下面,我们来看看每个部分函数实现:

1 - 单链表的创建:

单链表的创建可以使用:头插法或尾插法。我一般使用尾插法,因为头插法的数据与键盘输入的顺序相反,不习惯,因人而异吧.

a) : 头插法创建单链表,代码如下:

LinkList Creat_LinkList_1()//头插法创建单链表.

{

printf("Please enter linklist datas(END OF -1): ");

LinkList H = (LinkList)malloc(sizeof(LNode));

H->next=NULL;

LNode *s;

ElemType x;

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;

}

b) : 尾插法创建单链表,代码如下:

LinkList Creat_LinkList_2()//尾插法创建单链表.

{

printf("Please enter linklist datas(END OF -1): ");

LinkList H = (LinkList)malloc(sizeof(LNode));

H->next = NULL;

LNode *r = H;

LNode *s;

ElemType x;

scanf("%d",&x);

while(x!=-1){

s = (LinkList)malloc(sizeof(LNode));

s->data = x;

s->next = r->next;

r->next = s;

r = s;

scanf("%d",&x);

}

return H;

}

2 - 计算单链表的表长:

通过计数器来统计单链表中的结点个数,设计思路也很简单,代码如下:

int Length_LinkList(LinkList H)//计算表长.

{

int length=0;

LNode *p = H->next;

while(p){

p = p->next;

length++;

}

return length;

}

3 - 按值查找单链表的元素:

LinkList Locate_LinkList(LinkList H,ElemType x)//按值查找值为x的值.

{

LNode *p=H->next;

while(p->data != x && p){

p=p->next;

}

if(p->data == x) return p;

else return NULL;

}

4 - 按序号查找单链表的元素并返回结点指针值:(返回指针值,后面可以用到)

LinkList Get_LinkList(LinkList H,int k)//按序号查找第k个元素.

{

int j=0;

LNode *p = H->next;

while(p && j

p = p->next;

j++;

}

if(j == k ) return p;

else return NULL;

}

5 - 单链表的插入:

因为插入操作时,需要知道单链表插入位置的前一个结点的信息,所以利用上面的代码,可以快速定位:

int Insert_LinkList(LinkList H,int i,ElemType x)//插入数据.

{

LNode *p,*s;

p = Get_LinkList(H,i-1);//查找第i-1个结点.

if(p == NULL){

printf("\nInsert Location is Eroor.\n");

return ERROR;

}

else{

s = (LinkList)malloc(sizeof(LNode));

s->data = x;

s->next = p->next;

p->next = s;

return TRUE;

}

}

6 - 单链表的删除:

同理:单链表的删除更需要知道前一个结点的指针值,这样可以实现快速定位:

int Delete_LinkList(LinkList H,int i)//删除单链表中第i位置的元素.

{

LinkList p,q;

p = Get_LinkList(H,i-1);//查找第i-1个结点.

if(p == NULL){

printf("\nDelete Location is wrong!\n");

return ERROR;

}

else{

if(p->next==NULL){

printf("\nDelete Location is wrong!\n");

return ERROR;

}

else{

q=p->next;

p->next=q->next;

free(q);

return TRUE;

}

}

}

7 - 单链表的逆置:

逆置的中心思想:先断链,再头插。具体思路:先让H->next = NULL,然后将原来链表的数据挨个头插到头结点之后,便完成单链表的逆置,代码如下:

void Reverse_LinkList(LinkList H)//逆置单链表.

{

LinkList p,q;

p=H->next;

H->next=NULL; //方法:先断链,再头插.

while(p){

q=p;

p=p->next;

q->next=H->next;

H->next=q;

}

}

8 - 单链表中删除重复的值:(取重)

void Pur_LinkList(LinkList H)//在单链表中删除重复结点.

{

LNode *p,*q,*r;

p=H->next;

if(p!=NULL)

while(p->next){

q=p;

while(q->next)

{

if(q->next->data == p->data)

{

r = q->next;//找到后续结点,用r指向,删除*r.

q->next = r->next;

free(r);

}

else q = q->next;

}

p=p->next;

}

}

现在,我还是打算把自己写好的代码全部放上去,供大家学习交流使用:

#include

#include

#define ERROR 0

#define TRUE 1

typedef int ElemType;

typedef struct node

{

ElemType data;

struct node *next;

}LNode,*LinkList;

LinkList Creat_LinkList_1();//头插法创建单链表.

LinkList Creat_LinkList_2();//尾插法创建单链表.

int Length_LinkList(LinkList H);//计算表长.

LinkList Get_LinkList(LinkList H,int k);//按序号查找第k个元素.

LinkList Locate_LinkList(LinkList H,ElemType x);//按值查找值为x的值.

int Insert_LinkList(LinkList H,int i,ElemType x);//插入数据.

int Delete_LinkList(LinkList H,int i);//删除单链表中第i位置的结点.

void Reverse_LinkList(LinkList H);//逆置单链表.

void Pur_LinkList(LinkList H);//在单链表中删除重复结点.

void Print_LinkList(LinkList H);//打印单链表.

int main()

{

LinkList H = (LinkList)malloc(sizeof(LNode));

H = Creat_LinkList_2();

int length=0;

length = Length_LinkList(H);

printf("\nThe LinkList length is %d.\n",length);

int k;

LNode *p;

printf("\nPlease enter u wanna search node's num: ");

scanf("%d",&k);

p=Get_LinkList(H,k);

printf("\nThe Node's point is %d.\n",p);

ElemType x;

printf("\nPlease enter Insert Location and ElemType x:");

scanf("%d%d",&k,&x);

Insert_LinkList(H,k,x);

Print_LinkList(H);

printf("\nPlease enter delete nodenum:");

scanf("%d",&k);

Delete_LinkList(H,k);

Print_LinkList(H);

Reverse_LinkList(H);

Print_LinkList(H);

return 0;

}

LinkList Creat_LinkList_1()//头插法创建单链表.

{

printf("Please enter linklist datas(END OF -1): ");

LinkList H = (LinkList)malloc(sizeof(LNode));

H->next=NULL;

LNode *s;

ElemType x;

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;

}

LinkList Creat_LinkList_2()//尾插法创建单链表.

{

printf("Please enter linklist datas(END OF -1): ");

LinkList H = (LinkList)malloc(sizeof(LNode));

H->next = NULL;

LNode *r = H;

LNode *s;

ElemType x;

scanf("%d",&x);

while(x!=-1){

s = (LinkList)malloc(sizeof(LNode));

s->data = x;

s->next = r->next;

r->next = s;

r = s;

scanf("%d",&x);

}

return H;

}

int Length_LinkList(LinkList H)//计算表长.

{

int length=0;

LNode *p = H->next;

while(p){

p = p->next;

length++;

}

return length;

}

LinkList Get_LinkList(LinkList H,int k)//按序号查找第k个元素.

{

int j=0;

LNode *p = H->next;

while(p && j

p = p->next;

j++;

}

if(j == k ) return p;

else return NULL;

}

LinkList Locate_LinkList(LinkList H,ElemType x)//按值查找值为x的值.

{

LNode *p=H->next;

while(p->data != x && p){

p=p->next;

}

if(p->data == x) return p;

else return NULL;

}

int Insert_LinkList(LinkList H,int i,ElemType x)//插入数据.

{

LNode *p,*s;

p = Get_LinkList(H,i-1);//查找第i-1个结点.

if(p == NULL){

printf("\nInsert Location is Eroor.\n");

return ERROR;

}

else{

s = (LinkList)malloc(sizeof(LNode));

s->data = x;

s->next = p->next;

p->next = s;

return TRUE;

}

}

void Print_LinkList(LinkList H)//打印单链表.

{

printf("\nThe LinkList NodeData as following:");

LinkList p = H->next;

while(p!=NULL){

printf("%d ",p->data);

p = p->next;

}

printf("\n");

}

int Delete_LinkList(LinkList H,int i)//删除单链表中第i位置的元素.

{

LinkList p,q;

p = Get_LinkList(H,i-1);//查找第i-1个结点.

if(p == NULL){

printf("\nDelete Location is wrong!\n");

return ERROR;

}

else{

if(p->next==NULL){

printf("\nDelete Location is wrong!\n");

return ERROR;

}

else{

q=p->next;

p->next=q->next;

free(q);

return TRUE;

}

}

}

void Reverse_LinkList(LinkList H)//逆置单链表.

{

LinkList p,q;

p=H->next;

H->next=NULL; //方法:先断链,再头插.

while(p){

q=p;

p=p->next;

q->next=H->next;

H->next=q;

}

}

void Pur_LinkList(LinkList H)//在单链表中删除重复结点.

{

LNode *p,*q,*r;

p=H->next;

if(p!=NULL)

while(p->next){

q=p;

while(q->next)

{

if(q->next->data == p->data)

{

r = q->next;//找到后续结点,用r指向,删除*r.

q->next = r->next;

free(r);

}

else q = q->next;

}

p=p->next;

}

}

小结:

单链表这边的操作也不是很难,只要C语言指针的知识学的比较扎实。然后,也需要多加练习。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值