数据结构-C语言实现单链表plus版本,复制粘贴直接用
有哪些地方不明白的请看我单链表的博客,点下面的地址,博客里面有详细解释
单链表
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
void mainMenu()
{
printf("\n=========单链表操作程序========\n");
printf("======== 0 退出========\n");
printf("======== 1 头插========\n");
printf("======== 2 尾插========\n");
printf("======== 3 打印单链表=======\n");
printf("======== 4 头删========\n");
printf("======== 5 尾删========\n");
printf("======== 6 删除指定结点========\n");
printf("======== 7 按位置查找元素========\n");
printf("======== 8 按值查找元素========\n");
printf("======== 9 求链表长度========\n");
printf("======== 10 清空链表========\n");
}
//定义一个单链表
typedef struct LNode
{
int data;
struct LNode* next;
}LNode, * LinkList;
//初始化头结点
int InitLinkList(LinkList* L)
{
*L = (LinkList)malloc(sizeof(LNode));//为头结点分配空间
if (*L == NULL)
{
printf("开辟内存空间失败,初始化头结点失败\n");
return -1;
}
(*L)->next = NULL;
printf("单链表初始化成功....\n");
return 0;
}
//插入节点
int insertNode(LinkList *L,int i,int e)
{
if (i < 1)
return -1;
LNode* p = *L; //p为指向当前结点的指针
int j = 0; //p指针指向的当前结点,当前位置为头结点
//寻找i-1个节点
while (p != NULL && j < i - 1) {
p = p->next;
j++;
}
LNode* s = (LNode*)malloc(sizeof(LNode)); //创建新结点
if (s == NULL)
{
return -1;
}
s->data = e;
s->next = p->next;
p->next = s;
return 0;
}
//打印链表中的元素
int printLinkList(LinkList *L) {
LNode* p = *L; //p为指向当前结点的指针
//判断链表是否为空
if (p->next == NULL) {
printf("该链表为空\n");
return -1;
}
while (p->next!=NULL)
{
p = p->next;//跳过头结点
printf("%d ",p->data);
}
return 0;
}
int ListLength(LinkList* L)
{
LNode* p = *L; //p指针用于指向链表的首结点
int LinkListlegth = 0;
while (p->next != NULL)
{
p = p->next;
LinkListlegth++;
}
return LinkListlegth;
}
//获取链表中的某一个位置的元素
int GetElem(LinkList* L, int i)
{
int temp = 0;//存储查找的元素
LNode* p = *L; //p指针用于指向链表的首结点
int length = ListLength(L);//表长
if(i<1||i>length)
{
printf("查找位置不合法或者为空表\n");
return -1;
}
int j = 0;
//查找第七个元素,下标为6,所以让p指针指向下表为6的结点
while (p != NULL && j < i) {
p = p->next;
j++;
}
//当前结点的数据域中就是所要查找的元素
temp = p->data;
printf("你查找的%d位置的元素是:%d\n", i, temp);
return 0;
}
//删除链表中某个位置的元素
int DeleteList(LinkList* L, int i)
{
int temp = 0;//保存删除元素
LNode* pre, * p; //pre指向被删除结点的前一个结点,p指向被删除节点
pre = *L;
int j = 0;
//判断删除位置是否合法
int length = ListLength(L);//表长
if (i<1 || i>length)
{
printf("删除位置不合法或者为空表");
return -1;
}
//查找第i-1个节点
while (pre != NULL && j < i-1) {
pre = pre->next;
j++;
}
p = pre->next;
pre->next = p->next; //改变删除结点前驱结点的指针域
temp = p->data;
free(p);//释放删除结点的空间
printf("删除第%d个位置的元素为:%d\n", i, temp);
return 0;
}
//尾插法建立单链表
int InsertLinkListTail(LinkList* L,int n)
{
LNode* pnew = NULL;
LNode* ptail = *L;//尾节点
//找到尾节点进行尾插
while (ptail->next!=NULL)
{
ptail = ptail->next;
}
for (int i = 1; i <= n; i++)
{
pnew = (LinkList)malloc(sizeof(LNode));
if (pnew == NULL)
{
printf("error");
return -1;
}
int num = 0;
printf("请输入第%d个元素:\n",i);
scanf("%d", &num);
pnew->data = num;
pnew->next = NULL;
ptail->next = pnew;
ptail = pnew;//尾节点后移
}
return 0;
}
//尾删
int delTail(LinkList* L)
{
//LNode* p = *L;
LNode* tail = *L;//指向头结点
if (tail == NULL)
{
printf("错误\n");
return -1;
}
LNode* pre = NULL;
while (tail->next!=NULL)
{
pre = tail;//指向尾巴前一个指针
tail = tail->next;//指向尾巴的指针
}
pre->next = NULL;//删除尾节点
free(tail);//释放尾节点空间
printf("删除成功...\n");
return 0;
}
//头删
int delHead(LinkList* L)
{
LNode* pdel = NULL;//存储删除结点
//首先对表进行判空
if ((*L)->next == NULL)
{
printf("空表不能删除\n");
return -1;
}
pdel = (*L)->next;//要删除的结点
(*L)->next = pdel->next;//令头结点的next指向要删除的结点的下一个节点
free(pdel);//释放删除结点的内存
printf("删除成功....\n");
return 0;
}
//清空链表
int ClearLinkList(LinkList* L)
{
LNode* p = *L;
if (p->next==NULL)
{
printf("空表无法清空...");
return -1;
}
LNode* q = NULL;
while (p->next != NULL)
{
q = p->next;
p->next = q->next;
free(q);
}
return 0;
}
//头插建立单链表
int headInsert(LinkList* L, int n)
{
LNode* p = *L;
LNode* pnew = NULL;//新的节点
for (int i = 1; i <= n; i++)
{
pnew = (LinkList)malloc(sizeof(LNode));
if (pnew == NULL)
{
printf("error");
return -1;
}
int num = 0;
printf("请输入第%d个元素:\n", i);
scanf("%d", &num);
pnew->data = num;
pnew->next = (*L)->next;
(*L)->next = pnew;
}
return 0;
}
//按照值查找
int locatePos(LinkList* L, int e)
{
LNode* p = *L;//指向头结点
int i = 0;
int temp = 0;
while (p!=NULL)
{
if (p->data == e)
{
printf("找到了%d元素,是第%d个元素\n",e,i);
temp = p->data;
}
i++;
p = p->next;
}
if (temp != e)
{
printf("未找到%d元素\n",e);
}
}
int main()
{
int choice = 0;
int n = 0;
int length = 0;//链表的长度
//定义并初始化单链表
LinkList p = NULL;
//初始化单链表
InitLinkList(&p);
do
{
mainMenu();//主菜单
printf("请输入你的选择:\n");
scanf("%d", &choice);
switch (choice)
{
case 0:
printf("========再见!!!========\n");
break;
case 1:
printf("请输入你想要插入元素的个数:");
scanf("%d",&n);
headInsert(&p, n);
break;
case 2:
//尾插插建立单链表
printf("请输入你想要插入元素的个数:\n");
scanf("%d", &n);
InsertLinkListTail(&p, n);//尾插建立单链表
break;
case 3:
//打印单链表
printf("单链表中的数据为:");
printLinkList(&p);
break;
case 4:
//头删
delHead(&p);
break;
case 5:
//尾删
delTail(&p);
break;
case 6:
//删除指定结点
printf("请输入删除单链表元素的位置:");
scanf("%d", &n);
DeleteList(&p,n);
break;
case 7:
//按位置查找元素
printf("请输入查找元素的位置:");
scanf("%d", &n);
GetElem(&p, n);
break;
case 8:
//按值查找元素
printf("请输入查找的值:");
scanf("%d", &n);
locatePos(&p,n);
break;
case 9:
//求链表长度
length = ListLength(&p);
printf("链表的长度为:%d\n", length);
break;
case 10:
//清空链表
ClearLinkList(&p);
break;
default:
printf("输入有误...");
break;
}
} while (choice);
}