只能释放malloc…申请的指针
typedef:给类型起别名
带头节点的单链表
typedef int Elemtype;
typedef struct Linknode
{
Elemtype data;
struct Linknode* next;
}Linknode;//节点
typedef struct Linklist
{
struct Linknode* head;//头指针。
int cusize;
}Linklist;//链表
struct Linknode* buy_node()
{
struct Linknode* s = (struct Linknode*)malloc(sizeof(struct Linknode));
if (NULL == s)
{
exit(1);
}
memset(s, 0, sizeof(Linknode));
return s;
}
void Initlist(Linklist* plist)
{
assert(plist != NULL);
plist->head = buy_node();
plist->cusize = 0;
}
void Print(Linklist* plist)
{
assert(plist != NULL);
Linknode* p = plist->head->next;//让链表指针引用哨兵节点,(第一个节点)哨兵节点的next就是第二个节点的地址
while (p != NULL)
{
printf("%d ", p->data);
p=p->next;
}
printf("\n");
}
Linknode* Find(Linklist* plist, Elemtype val)
{
assert(plist != NULL);
Linknode* p = plist->head->next;//将哨兵节点的下一个节点的地址赋给结点指针
while (p != NULL && p->data != val)
{
p = p->next;
}
return p;
if (NULL == p)
{
return NULL;
}
}
Linknode* Find_prev(Linklist* plist, Elemtype val)//寻找val值,返回前一个
{
assert(plist != NULL);
Linknode* p = plist->head;//将哨兵接待节点的地址赋值给节点指针
Linknode* pre = NULL;
while (p != NULL && p->data != val)
{
pre = p;
p = p->next;
}
if (p == NULL)
{
pre = NULL;
}
return pre;
}
Linknode* Find_prev1(Linklist* plist, Elemtype val)//寻找val值,返回前一个
{
assert(plist != NULL);
Linknode* p = plist->head;//将哨兵接待节点的地址赋值给节点指针
while (p != NULL && p->next->data != val)//判断下一个节点的data值是否等于val
{
p = p->next;
}
if (p == NULL)
{
p = NULL;
}
return p;
}
bool Insert(Linklist* plist, Linknode* p, Elemtype val)//在p之后插入一个节点
{
assert(plist != nullptr);
if (p == NULL)
{
return false;//失败
}
Linknode* s = buy_node();//先给要插入的节点申请一块空间,用s指向它
s->next = p->next;//给插入节点的next指针赋值为前一个指针的next指针
p->next = s; //将前一个节点的next指针赋值为本节点地址
plist->cusize += 1;//总结 先勾右再勾左
s->data = val;//给插入的节点赋值
return true;//成功
}
void Inser_prev(Linklist* plist, Elemtype val)
{
Insert(plist, plist->head,val);//在哨兵节点之后插
}
void Inser_end(Linklist*plist,Elemtype val)
{
assert(plist != NULL);
if (plist->cusize == 0)
{
Inser_prev(plist, val);
}
else
{
Linknode* p = plist->head;//只想哨兵节点
while (p->next!= NULL)
{
p = p->next;
}
Insert(plist, p, val);
}
}
Linknode* FindPos(const Linklist* plist, int pos)//pos的值如果等于除去哨兵节点后的第n个节点,就返回第n个结点的地址
{
assert(plist != NULL);
int z = 0;
struct Linknode* p = plist->head;//指向哨兵节点
if (pos<1 || pos>plist->cusize)
{
return NULL;
}
else
{
while (p->next!=NULL||pos != z)
{
p=p->next;
z += 1;
}
return p;
}
}
Linknode* FindPos_Prev(const Linklist* plist, int pos)//pos的值如果等于除去哨兵节点后的第n个节点,就返回第n-1个结点的地址
{
assert(plist != NULL);
if (pos<1 || pos>plist->cusize+1)
{
return NULL;
}
else
{
int i = 0;
Linknode* p = plist->head;
while (pos-1 != i)
{
p = p->next;
i++;
}
return p;
}
}
bool Erase_Next(Linklist* plist, Linknode* ptr)//删除*ptr的下一个节点
{
assert(plist != NULL);
Linknode* p = ptr->next;
if (ptr->next == NULL)
{
return false;
}
else
{
ptr->next = p->next;
free(p);
plist->cusize--;
return true;
}
}
void Pop_Front(Linklist* plist)//头删法
{
assert(plist != NULL);
Erase_Next(plist, plist->head);
}
void Pop_back(Linklist* plist)//尾删
{
assert(plist != NULL);
/*Linknode* p = plist->head;
while (p->next != NULL)
{
p = p->next;
}//找到倒数第二个节点的地址*/
Linknode* p = FindPos_Prev(plist, plist->cusize);
Erase_Next(plist, p);
}
int main()
{
int ar[] = { 12,23,34,45,56,67,78,89,90 };
int n = sizeof(ar) / sizeof(ar[0]);
Linklist mylist;//定义链表变量
Initlist(&mylist);//初始化链表,给链表内的head申请空间,就是第一个节点,申请的空间是一个节点指针
for (int i =0; i < n; i++)
{
Inser_prev(&mylist, ar[i]);
Print(&mylist);
}
}