#include<stdio.h>
#include<stdlib.h>
typedef int ElemType; //int类型改别名为ElemType
typedef struct LNode //单链表的定义
{
/* data */
ElemType data;
struct LNode *next;
}LNode,*LinkList;
/* 初始化操作 */
int InitList(LinkList *L) //带头结点的单链表初始化
{
(*L) = (LNode *)malloc(sizeof(LNode));
if(*L == NULL)
return -1; //内存分配失败
(*L)->next = NULL;
return 1;
}
/* 链表输出 */
//输出单链表
void DispList(LinkList L)
{
LNode *p = L->next;
if (p == NULL)
{
printf("该链表为空");
}
while (p!=NULL)
{
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
/* 判空操作 */
//判断是否为空表
int isEmptyList(LinkList L)
{
if ((L->next) == NULL)
{
return -1;
}else{
return 1;
}
}
/* 销毁操作 */
//销毁单链表
int DestoryLinkList(LinkList *L)
{
LNode* p;
while (*L)
{
p = *L;
(*L) = (*L)->next;
free(p);
}
return 1;
}
/* 求表长 */
//求表长
int LinkListLen(LinkList L)
{
int length = 0;
while (L->next != NULL)
{
length++;
L = L->next;
}
return length;
}
/* 建表操作 */
//头插法建立单链表
int CreateList_HeaderInsert(LinkList *L,int n)
{
*L = (LinkList)malloc(sizeof(LNode)); //头节点
if(*L==NULL)
return -1;//分配内存失败
(*L)->next = NULL;
int i=0;
int k=0;
for(i=0;i<n;i++)
{
LNode *p = (LNode *)malloc(sizeof(LNode));
if (p = NULL)
return -1;
scanf("%d",&k);
p->data = k;
p->next = (*L)->next;
(*L)->next = p;
}
}
//尾插法建表
int CreateList_TailerInsert(LinkList *L,int n)
{
(*L) = (LinkList)malloc(sizeof(LNode)); //头节点
if((*L)==NULL)
return -1; //内存分配失败
int i=0;
int k=0;
LNode *r = (*L);
for (i=0;i<n;i++)
{
LNode *s = (LNode *)malloc(sizeof(LNode));
scanf("%d",&k);
s->data = k;
r->next = s;
r = s; //更新尾指针
}
r->next = NULL; //尾指针置空
return 1;
}
/* 查询操作 */
//按位取值--------按位查找
int GetElem(LinkList L,int i,int *e)
{
if(i<1)
return -1; //位置不合法
LNode* p = L->next;
int count=1;
while (p!=NULL && count<i)
{
p = p->next;
count++;
}
if (p==NULL || count>i)
{
return -1;
}else{
*e = p->data;
return 1;
}
}
//按值查找
int LocateElem(LinkList L,int num)
{
int count = 1;
LNode *p = L->next;
while (p!=NULL && p->data!=num)
{
p = p->next;
count++;
}
if (p == NULL)
return -1;
else{
return count;
}
}
/* 删除操作 */
//按位序删除-----删除位序为i的节点-------先找到它的前驱节点也就是i-1节点
int DeleteByPostion(LinkList *L,int i,int *e)
{
if (i<1)
return -1; //位置不合法
LNode *p = (*L);
int j = 0;
while (p!=NULL && j<i-1) //找到第i-1个位置
{
p = p->next;
j++;
}
if (p==NULL)
return -1; //位置不合法
if (p->next==NULL)
return -1; //i-1之后无其他节点
LNode *q = p->next;
*e = q->data;
p->next = q->next;
free(q);
return 1;
}
//按值删除
int DeleteByValue(LinkList *L,int num)
{
LNode *p = (*L);
LNode *prev = NULL;
while (p!=NULL && p->data!=num)
{
prev = p;
p = p->next;
}
if (p == NULL)
return -1;//链表中查无此值
if (prev == NULL) //表明要删除的是头节点
{
(*L) = p->next;
free(p);
}else{
prev->next = p->next; //不是头节点的情况
free(p);
}
return 1;
}
/* 插入操作 */
//指定节点后插操作 ---------------在节点p之后插入元素e
int InsertNextNode(LNode *p,int e)
{
if (p==NULL)
return -1;
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s==NULL)
{
return -1; //内存分配失败
}
s->data = e;
p->next = s->next;
p->next = s;
return 1;
}
//指定节点前插操作---------------在节点p之前插入元素e
int InsertPriorNode(LNode *p,int e)
{
if (p==NULL)
return -1;
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s==NULL)
return -1; //内存分配失败
s->next = p->next; //s 接在 p 之后
p->next = s;
s->data = p->data; // s p 的值互换
p->data = e;
return 1;
}
//按位序插入-----找到i-1号节点并进行后插操作
int InsertListBySeq(LinkList *L,int i,int e)
{
if (i<1)
return -1; // 位置非法
LNode *p = (*L);
int j = 0;
while (p != NULL && j<i-1) // 找到i-1 个位置然后进行后插
{
p = p->next;
j++;
}
if (p == NULL)
return -1; //位置非法
//后插操作 InsertNextNode(LNode *p,int e)
LNode *s = (LNode *)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return 1;
}
//按位序插入----------找到i号节点并进行前插操作
int InsertListBySeq2(LinkList *L,int i,int e)
{
if (i<1)
return 1;//位置非法
LNode *p = (*L);
int j = 0;
while (p != NULL && j<i) // 找到i号位置然后进行前插
{
p = p->next;
j++;
}
if (p == NULL)
return -1; //位置非法
//前插操作
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s==NULL)
return -1;//内存分配失败
//指定节点前插操作
s->next = p->next;
p->next = s;
s->data = p->data;
p->data = e;
return 1;
}
//指定元素值前插入
int InsertHeadByItemValue(LinkList *L,int item,int Value)
{
LNode *p = (*L);
LNode *pre = NULL;
while (p!=NULL && p->data!=item)
{
pre = p;
p = p->next;
}
if (p == NULL)
return -1;//链表查无此值
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL)
return -1;//内存分配失败
s->data = Value;
s->next = p;
if (pre == NULL) //目标节点为头节点,则需要更新头节点
(*L) = s;
else
pre->next = s; //将s接入原链表
return 1;
}
//指定元素值后插入
int InsertNextByItemValue(LinkList *L,int item,int Value)
{
LNode *p = (*L);
while (p!=NULL && p->data!=item)
{
p = p->next;
}
if (p == NULL)
return -1;//单链表查无此值
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s==NULL)
return -1;//内存分配失败
s->data = Value;
s->next = p->next;
p->next = s;
return 1;
}
int main()
{
LinkList L;
InitList(&L);
int a = 0;
//printf("你想要用几个元素使用头插法建表:\n");
printf("你想要用几个元素使用尾插法建表:\n");
scanf("%d",&a);
//CreateList_HeaderInsert(&L,a);
CreateList_TailerInsert(&L,a);
printf("当前链表的元素为:");
DispList(L);
printf("\n");
printf("该链表是否为空表:");
int flag = 0;
flag = isEmptyList(L);
if (flag == -1)
{
printf("YES");
}else{
printf("NO");
}
printf("\n");
int length = LinkListLen(L);
printf("当前链表的长度为:%d",length);
printf("\n");
int position = 0;
printf("请输入position:");
scanf("%d",&position);
int flag2 = 0;
int e = 0;
flag2 = GetElem(L,position,&e);
if (flag2==-1)
{
printf("位置不合法");
}else{
printf("第%d位元素是%d",position,e);
}
printf("\n");
printf("你想要查找的元素值为:");
int num = 0;
scanf("%d",&num);
int flag3 = 0;
flag3 = LocateElem(L,num);
if (flag3 == -1)
{
printf("查找失败,链表中无此元素!");
}else{
printf("查找成功,该元素在链表中的序号为:%d",flag3);
}
printf("\n");
printf("你想要删除的元素位序为:");
int pos = 0;
scanf("%d",&pos);
int flag4 = 0;
int e4 = 0;
flag4 = DeleteByPostion(&L,pos,&e4);
if (flag4==-1)
{
printf("删除失败,位置不合法!");
}else{
printf("删除成功,被删除的元素为%d\n",e4);
}
printf("删除之后的单链表为:");
DispList(L);
printf("\n");
printf("你想要删除的元素值为");
int ItemValue = 0;
scanf("%d",&ItemValue);
int flag5 = 0;
flag5 = DeleteByValue(&L,ItemValue);
if (flag5==-1)
printf("删除失败,该链表中不存在此元素");
if (flag5==1)
printf("删除成功,删除该元素之后的链表为:");
DispList(L);
printf("按位序操作,在指定位序插入相应元素-----使用后插操作");
int InsertBySeqPos = 0;
printf("请输入你想插入的位置:\n");
scanf("%d",&InsertBySeqPos);
int InsertBySeqNum = 0;
printf("请输入你想插入的值:\n");
scanf("%d",&InsertBySeqNum);
int flag6 = 0;
flag6 = InsertListBySeq(&L,InsertBySeqPos,InsertBySeqNum);
if (flag6 == -1)
printf("插入失败,元素位置不合法");
else{
printf("插入成功");
DispList(L);
}
printf("\n");
printf("按位序操作,在指定位序插入相应元素--------使用前插操作");
int InsertBySeqPos2 = 0;
printf("请输入你想插入的位置:\n");
scanf("%d",&InsertBySeqPos2);
int InsertBySeqNum2 = 0;
printf("请输入你想插入的值:\n");
scanf("%d",&InsertBySeqNum2);
int flag7 = 0;
flag7 = InsertListBySeq2(&L,InsertBySeqPos2,InsertBySeqNum2);
if (flag7 == -1)
printf("插入失败,元素位置不合法");
else{
printf("插入成功");
DispList(L);
}
printf("\n");
int Item = 0;
int Value = 0;
printf("请输入你想插入到哪个元素之前");
scanf("%d",&Item);
printf("请输入你想插入的元素值");
scanf("%d",&Value);
int flag8 = 0;
flag8 = InsertHeadByItemValue(&L,Item,Value);
if (flag8 == -1){
printf("插入失败,单链表中无此值!");
}else{
printf("插入成功,插入之后的单链表为:");
DispList(L);
}
printf("\n");
int Item2 = 0;
int Value2 = 0;
printf("请输入你想插入到哪个元素之后");
scanf("%d",&Item2);
printf("请输入你想插入的元素值");
scanf("%d",&Value2);
int flag9 = 0;
flag9 = InsertNextByItemValue(&L,Item2,Value2);
if (flag9 == -1)
printf("插入失败,链表中没有此元素!");
else{
printf("插入成功,插入后的链表为:");
DispList(L);
}
DestoryLinkList(&L);
}
数据结构-----------单链表定义以及基本操作
于 2024-07-20 12:33:13 首次发布