#include<stdio.h>
#include<stdlib.h>
#define initSize 10//最大长度
typedef struct LNode//这里的LNode不能省略,因为结构体内部有LNode,若省略,在调用next成员时会出问题
{
int data;
struct LNode* next;
}LNode,*LinkList;
//LNode* = LinkList , 只是含义不同
//初始化单链表(带头结点)
bool initList(LinkList& L)
{
L = (LNode*)malloc(sizeof(LNode));
if (L == NULL)
return false;
L->next = NULL;
return true;
}
//头插法建立单链表 --(应用-链表逆置)
LinkList listHeadInsert(LinkList& L)
{
int data;
L = (LinkList)malloc(sizeof(LNode));
LNode* newNodetemp;
L->next = NULL;//头插法一定要在开始初始化,而尾插法可在最后用尾部指针指向NULL即可
scanf_s("%d", &data);
while (data != 9999)
{
newNodetemp = (LNode*)malloc(sizeof(LNode));
newNodetemp->data = data;
newNodetemp->next = L->next;
L->next = newNodetemp;
scanf_s("%d", &data);
}
return L;
}
//尾插法建立单链表
LinkList listTailInsert(LinkList& L)
{
int data;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;//最好建头结点时就加上初始化,或者下面在最后也可以
LNode *newNodetemp,* las = L;//las指向最后一个结点
scanf_s("%d", &data);
while (data!=9999)
{
newNodetemp = (LNode*)malloc(sizeof(LNode));
newNodetemp->data = data;
las->next = newNodetemp;
las = newNodetemp;
scanf_s("%d", &data);
}
las->next = NULL;
return L;
}
//时间复杂度为O(n)的前插操作:用头结点遍历,找到p的前驱
//时间复杂度为O(1)的前插操作:
bool insertPriorNode(LNode* p, int dataIn)
{
if (p == NULL);
return false;
LNode* newNode = (LNode*)malloc(sizeof(LNode));
if (newNode == NULL)//消除C6011警告,防止没有malloc成功
return false;
newNode->next = p->next;
p->next = newNode;
newNode->data = p->data;
p->data = dataIn;
return true;
}
//后插操作:在指定结点p之后插入元素
bool insertNextNode(LNode* p, int dataIn)
{
if (p == NULL);
return false;
LNode* newNode = (LNode*)malloc(sizeof(LNode));
if (newNode == NULL)
return false;
newNode->data = dataIn;
newNode->next = p->next;
p->next = newNode;
return true;
}
//按位序i插入元素(带头结点)
//时间复杂度:O(n)
//#define NO_HEAD_NODE//无头结点时
bool listInsert(LinkList& L, int i, int dataIn)
{
if (i < 1)
return false;
#ifdef NO_HEAD_NODE
/* 因为如果有头结点,那么所有插入操作都是在对“下一个”结点操作,而如果
* 没有头结点,恰又是对第一个结点操作,那么这时候是对“当前”结点操作
*/
if (i == 1)
{
LNode* newNode = (LNode*)malloc(sizeof(LNode));
if (newNode == NULL)
return false;
newNode->data = dataIn;
newNode->next = L;
L = newNode;
return true;
}
#endif // N0_HEAD_NODE
LNode* p;
p = L;//L指向头结点
int j = 0;
while (p != NULL && j < i - 1)//这里用for没有while方便,用while下一步直接可以判断i值是否合理
{
p = p->next;
j++;
}
/*此句已在后插操作加入
* if (p == NULL);//i值不合法
return false;
*/
insertNextNode(p, dataIn);//后插操作
return true;
}
//时间复杂度为O(1)的:删除指定结点p(只适用p不是最后一个结点!,否则只能从头遍历找前驱)
bool deleteNode(LNode* p)
{
if (p == NULL)
return false;
LNode* temp = p->next;
p->data = p->next->data;//把p的下一个赋给p,这样就不需要找p的前驱
p->next = temp->next;
free(temp);
return true;
}
//按位序删除
bool listDelete(LinkList& L, int i, int& dataDel)
{
if (i < 1)
return false;
LNode* p;
p = L;//L指向头结点
int j = 0;
while (p != NULL && j < i - 1)
{
p = p->next;
j++;
}
if (p == NULL)//i不合法
return false;
if(p->next==NULL)//p即最后一个或更后面,i不合法
return false;
LNode* temp = p->next;
dataDel = temp->data;
p->next = temp->next;
free(temp);
return true;
}
int main()
{
LinkList L;
initList(L);
//listTailInsert(L);
listHeadInsert(L);
int dataD;
listDelete(L, 1, dataD);
for (int i = 0; i < 3; i++)
{
printf("%d\n",L->next->data);
L=L->next;
}
return 0;
}
数据结构(2)_单链表操作
最新推荐文章于 2024-07-24 22:34:26 发布