C语言实现链表基本操作
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef int ElemType;
// 定义结点类型(也可以说是定义链表结构)
typedef struct Node
{
ElemType data;
struct Node *next;
} LinkList; // Node, *LinkList;
// Node表示结点的类型,*LinkList,表示指向Node节点类型的指针类型
// 函数声明,若不声明可能会报错
LinkList *initList(LinkList *L);
LinkList *createList(int len);
int insertLinkList(LinkList *L, int pos, ElemType e);
int deleteLinkList(LinkList *L, int pos, ElemType *e);
void reverseLinkList(LinkList *L);
int searchLinkList(LinkList *L, ElemType e);
int getLen(LinkList *L);
int isEmpty(LinkList *L);
void printLinkList(LinkList *L);
int main()
{
LinkList *L;
ElemType e;
int len, pos;
printf("创建元素个数:");
scanf("%d", &len);
printf("\n请输入:");
L = createList(len);
printf("\n当前链表所有元素:");
printLinkList(L);
printf("\n插入位置和插入值(中间用空格隔开):");
scanf("%d%d", &pos, &e);
insertLinkList(L, pos, e);
printf("\n插入元素后链表所有元素:");
printLinkList(L);
printf("\n请输入删除元素位置:");
scanf("%d", &pos);
deleteLinkList(L, pos, &e);
printf("\n元素%d已删除", e);
printf("\n删除后链表所有元素:");
printLinkList(L);
printf("\n请输入查找元素:");
scanf("%d", &e);
if (searchLinkList(L, e) != -1)
{
printf("\n%d位于:%d", e, searchLinkList(L, e));
}
else
printf("\n%d未找到", e);
reverseLinkList(L);
printf("\n转置后链表所有元素:");
printLinkList(L);
return 0;
}
// 链表初始化,创建头节点
LinkList *initList(LinkList *L)
{
L = (LinkList *) malloc(sizeof(LinkList)); // 为头节点分配空间
L->next = NULL; // 头节点指针域置空
return L;
}
// 创建指定个数的单链表
LinkList *createList(int len)
{
int i;
ElemType e;
LinkList *L = initList(L), *r, *n; // 分别定义头指针、尾指针(独立于链表的指针,存在目的是为了指明新元素插入位置)、新指针(插入的新元素的指针)
r = L; // 尾指针初始化为头指针
for (i = 0; i < len; i++)
{
scanf("%d", &e);
n = (LinkList *)malloc(sizeof(LinkList)); // 申请空间
n->data = e;
n->next = NULL; // 新指针指针域置空
r->next = n; // 将新指针链入单链表末尾
r = r->next; // 尾指针往后移
}
return L;
}
// 将新元素插入指定位置
int insertLinkList(LinkList *L, int pos, ElemType e)
{
if (pos < 1 || pos > getLen(L) + 1) return 0; // 插入错误
LinkList *r = L, *n; // 前面是访问头节点,后面是新建一个结构体n,代表插入的节点
n = (LinkList *)malloc(sizeof(LinkList)); // 申请节点空间
n->data = e; // 为节点赋值
n->next = NULL;
while (--pos > 0)
{
r = r->next; // 将尾指针移动到插入位置
}
n->next = r->next; // 将新指针(即将插入结构体的指针)赋值给尾指针
r->next = n;
return 0;
}
// 将指定位置元素删除
int deleteLinkList(LinkList *L, int pos, ElemType *e)
{
if (pos < 1 || pos > getLen(L))
return 0; // 删除位置错误
LinkList *r = L, *d; // r访问头节点,d访问删除节点并存储数据
while (--pos > 0)
{
r = r->next; // 将为指针移动到删除位置
}
d = r->next; // 删除元素节点
*e = d->data; // 保存删除元素值
r->next = d->next; // 将尾指针跳过删除节点,链入下一个节点
free(d); // 释放删除节点
return 0;
}
// 转置单链表:采用头插法
void reverseLinkList(LinkList *L)
{
if (L == NULL || L->next == NULL)
return ;//return L; // 链表为空或链表元素为1
LinkList *r = L->next, *cur = NULL, *last = NULL; // 定义尾指针(访问头指针),欲插入指针,遍历指针
cur = last= r->next;
r = NULL;
while (last != NULL)
{
last = last->next; // last指向后一个节点(last作为遍历指针)
cur->next = r; // cur指针,使当前节点指针域指向前一节点
L->next =cur; //使头指针指向当前节点
r = cur; // 向后移动r指针,往后的循环使原链表的元素指针指向前一个元素
cur = last; // 向后移动cur指针
}
}
// 查找指定元素,返回指定元素位序
int searchLinkList(LinkList *L, ElemType e)
{
if (isEmpty(L))
return -1;
int pos = 1; // 位序从1开始,下标从0开始
LinkList *r = L->next;
while (r)
{
if (r->data == e)
{
return pos; // 找到指定元素,返回位序
// break;
}
r = r->next; // 指针后移
pos++;
}
return -1; // 遍历完成仍未找到
}
// 获取链表长度
int getLen(LinkList *L)
{
if (L->next == NULL)
return 0;
int len = 0;
// LinkList *r = L;
// while (r)
// {
// r = r->next; // 指针后移
// len++;
// }
while (L){
L = L->next;
len++;
}
return len;
}
// 判断链表是否为空
int isEmpty(LinkList *L)
{
return !L->next; // L->next == NULL也可以
}
// 打印链表
void printLinkList(LinkList *L)
{
LinkList *r;
r = L->next;
while (r)
{
printf("%d -> ", r->data);
r = r->next;
}
}