#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct node
{
int data;
struct node *next;
}LNode,*Linklist;
bool initlist(Linklist *l) //初始化一个带头结点的单链表
{
(*l) = (LNode*)malloc(sizeof(LNode)); //分配一个头结点
if((*l)==NULL) //内存不足分配失败
return false;
(*l)->next=NULL; //头结点之后暂时还没有节点
return true;
}
bool empty(Linklist l) //判断带头结点的单链表是否为空
{
if(l->next==NULL)
return true;
else
return false;
}
bool listinsert(Linklist l, int i, int e)//按位序插入,在第i个位置插入元素e
{
if(i<1)
return false;
LNode *p; // 指针p指向当前扫描到的结点
int j=0; //当前p指向的是第几个结点
p = l; //l指向头结点,头结点是第0个结点(不存数据)
while (p != NULL && j < i - 1) { //循环找到第i-1个结点
p=p->next; //如果i不是合法的结点,那么p循环往后的时候就会指向NULL
j++; //然后退出循环,此时p的值为NULL
}
if(p==NULL) //i值不合法
return false;
LNode *s = (LNode*)malloc(sizeof(LNode));
s->data=e;
s->next = p->next;
p->next = s;
return true;
}
bool insertnextnode(LNode* p, int e)//指定结点的后插操作
{
if(p==NULL)
return false;
LNode *s=(LNode*)malloc(sizeof(LNode));
if(s==NULL) //内存分配失败
return false;
s->data=e;
s->next =p->next;
p->next = s; //将结点s连接到p之后
return true;
}
bool insertpriornode(LNode* p, int e) //前插操作:在p结点之前插入元素e (实际上是在p之后做了后插结点操作再交换两个结点的值)
{ //(时间复杂度O(1))
if(p==NULL)
return false;
LNode *s = (LNode*)malloc(sizeof(LNode));
if(s==NULL)
return false;
s->next=p->next;
p->next =s; //将新结点s连接到p之后
s->data=p->data; //将p元素的值复制到s中
p->data=e; //p中元素覆盖为e
return true;
}
bool listdelete(Linklist l, int i, int* e)//按位序删除,删除表中第i个元素,其实就是找到第i-1个结点,将其指针指向第i+1个结点,并释放第i个结点
{
if(i<1)
return false;
LNode*p; //指针p指向当前扫描到的结点
int j=0; //当前p指向的是第几个结点
p=l; //先让p指向头结点
while (p != NULL && j < i - 1) { //循环找到第i-1个结点
p=p->next;
j++;
}
if(p==NULL)
return false;
if(p->next==NULL) //第i-1个结点之后已经没有其他结点
return false;
LNode* q =p->next; //令q指向被删除结点
*e = q->data; //用e返回元素的值
p->next = q->next; //将*q结点从链中"断开"
free(q); //释放结点的存储空间
return true; //删除成功
}
bool deletenode(LNode* p) //指定结点的删除操作:需要修改其前驱结点的next指针,方法1:传入头指针,循环找到p的前驱结点。方法2:偷天换日(类似于结点前插操作)
{
if(p==NULL)
return false;
if(p->next==NULL) //如果*p为最后一个结点我们只能通过从表头开始依次寻找p的前驱,时间复杂度O(n)
return false;
LNode *q= p->next; //让q指向p的后继结点
p->data=q->data; //和后继结点交换数据域,p不存在后继结点我们访问后继节点的数据是错误的
p->next=q->next;
free(q);
return true;
}
LNode* getelem(Linklist l, int i) //带头结点的按位查找
{
if(i<0)
return NULL;
LNode *p; //指针p指向当前扫描到的结点
int j=0; //当前p指向的是第几个结点
p=l; //先让p指向头结点,头结点是第0个结点(不存数据)
while (p != NULL && j < i) { //循环找到第i个结点
p=p->next;
j++;
}
return p;
}
//按值查找,找到数据域==e的结点
LNode* locateelem(Linklist l, int e) //带头结点的按值查找
{
LNode *p = l->next; //p指向第1个结点
while (p != NULL && p->data != e) {
p=p->next;
}
return p; //找到后返回该结点指针,否则返回NULL
}
int length(Linklist l) //求单链表的长度
{
int len =0;
LNode *p = l;
while (p->next != NULL) {
p=p->next;
len++;
}
return len;
}
Linklist creat_withhead_by_tailinsert(Linklist* l) //尾插法建立带头结点的单链表
{
int x;
scanf("%d",&x);
(*l)=(LNode*)malloc(sizeof(LNode)); //建立头结点,不存数据
LNode *s,*r =(*l); //尾指针指向新结点,s和r一开始都指向头结点
while (x != 9999) {
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s; //尾指针指向新结点
scanf("%d",&x);
}
r->next=NULL; //循环建立链表结束不要忘了使最后一个结点的指针指向NULL
return (*l);
}
Linklist creat_withhead_by_headinsert(Linklist* l) //头插法建立带头结点的单链表
{
int x;
scanf("%d",&x);
(*l)=(LNode*)malloc(sizeof(LNode)); //建立头结点,不存数据
(*l)->next=NULL; //初始化为空链表 如果不把指针指向NULL可能指向一片神秘不可知的地方
LNode *s;
while (x != 9999) {
s=(LNode*)malloc(sizeof(LNode));
s->data=x;
s->next=(*l)->next;
(*l)->next=s; //将新结点插入表中,*l为头指针
scanf("%d",&x);
}
return (*l);
}
bool print(Linklist l)
{
LNode *p;
p=l;
if(p->next==NULL)
return false;
while (p->next != NULL) {
printf("%d\n",p->next->data);
p=p->next;
}
return true;
}
int main()
{
Linklist list=NULL; //定义一个指向单链表的指针
//creat_withhead_by_tailinsert(&list);
creat_withhead_by_tailinsert(&list);
printf("%d##\n",length(list));
print(list);
listinsert(list,1,99);
print(list);
printf("%d##\n",length(list));
return 0;
}
07-21
1299
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交