/*初始化链表,有头结点(增加头结点会在某些算法上变简洁)*/
#include"Slist.h"
void InitList(List *list)
{
list->first = list->last = (PNode)malloc(sizeof(Node));
assert(list->first != NULL);
list->first->next = NULL; //初始化时应使头结点指针域为空,若不为空头插法执行后遍历最后一个节点的指针域又脏数据,程序会崩溃
list->size = 0;
}
/*尾插(顺序插入)*/
void push_back(List *list, ElementType x)
{
PNode p = list->last;
p = p->next = (PNode)malloc(sizeof(Node));
p->data = x;
p->next = NULL;
list->last = p;
list->size++;
}
/*头插(逆序插入)*/
void push_front(List *list, ElementType x)
{
PNode p = list->first;
PNode s = (PNode)malloc(sizeof(Node));
s->data = x;
s->next = p->next;
p->next = s;
if(list->size == 0)
{
list->last = s;
}
list->size++;
}
void show_list(List list)
{
PNode p = list.first->next;
while(p != NULL)
{
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
/*尾部删除*/
void pop_back(List *list)
{
if(list->size == 0)
{
return;
}
PNode p = list->first;
while (p->next != list->last)
{
p = p->next;
}
p->next = NULL;
free(list->last);
list->last = p;
list->size--;
}
/*头部删除*/
void pop_front(List *list)
{
if(list->size == 0)
{
return;
}
PNode p = list->first;
PNode s = p->next;
p->next = s->next;
free(s);
s = NULL;
/*考虑所删节点为最后一个节点时last的指向*/
if(list->size == 1)
{
list->last = list->first;
}
list->size--;
}
/*按顺序插入元素*/
void insert_val(List *list, ElementType x)
{
if(list->size == 0)
{
push_back(list,x);
return;
}
PNode p = list->first;
PNode s = (PNode)malloc(sizeof(Node));
s->data = x;
/*p->next!=NULL代表x是该链表最大的元素,则需要特殊操作,使last指针指向s*/
while(p->next != NULL && x > p->next->data)
{
p = p->next;
}
if(p->next == NULL)
{
list->last = s;
}
s->next = p->next;
p->next = s;
list->size++;
}
/*查找元素*/
PNode find(List *list, ElementType key)
{
if(list->size == 0)
{
return NULL;
}
PNode p = list->first->next;
while (p != NULL && key != p->data)
{
p = p->next;
}
return p;
}
int length(List list)
{
return list.size;
}
/*方法一:find方法查找到p节点,从头遍历至p的前驱节点*/
/*方法二:find方法查找到p节点,将后一个节点的data域复制至p节点,再删除后一个节点*/
void delete_val(List *list, ElementType x)
{
if (list->size == 0)
{
printf("list empty!\n");
return;
}
PNode p,s;
p = find(list,x);
if(p == NULL)
{
printf("%d is not exist!\n",x);
return;
}
s = p->next;
/*所删除节点是最后一个节点,执行尾部删除操作*/
if(p == list->last)
{
pop_back(list);
}
else
{
p->data = s->data;
p->next = s->next;
free(s);
s = NULL;
list->size--;
}
}
/*将整个链表分为两个链表,依次取一个节点按值插入*/
void sort(List *list)
{
if(list->size == 0 || list->size == 1)
{
return;
}
/*先将链表断开*/
PNode p,s,q;
s = list->first->next;
list->last = s;
q = s->next;
list->last->next = NULL;
/*将一个链表中的节点依次取出,按值插入另一个链表*/
while(q != NULL)
{
s = q;
q = s->next;
p = list->first;
while (p->next != NULL && p->next->data < s->data)
{
p = p->next;
}
if(p->next == NULL)
{
list->last = s;
}
s->next = p->next;
p->next = s;
}
}
/*将整个链表分为两个链表,依次取一个节点进行头插*/
void reserve(List *list)
{
if(list->size == 0 || list->size == 1)
{
return;
}
PNode p,q,s;
s = list->first->next;
q =s->next;
list->last = s;
list->last->next = NULL;
list->size = 1;
while(q != NULL)
{
s = q;
q = q->next;
push_front(list,s->data);
/*方法二:不更改list的size,直接进行头插*/
// s->next = list->first->next;
// list->first->next = s;
}
}
void clear(List *list)
{
if(list->size == 0)
{
return;
}
PNode p = list->first->next;
while(p != NULL)
{
list->first->next = p->next;
free(p);
p = list->first->next;
}
list->size = 0;
list->last = list->first;
return;
}
void destroy(List *list)
{
clear(list);
free(list->first);
list->first = list->last= NULL;
return;
}
// /*创建一个链表(带头结点的头插法,逆序插入)*/
// void CreateList(List *head)
// {
// List p,s;
// ElementType x;
// p = (*head);
// printf("请输入要输入链表元素->");
// while(scanf("%d",&x),x!=-1)
// {
// s = (List)malloc(sizeof(ListNode));
// s->data = x;
// s->next = p->next;
// p->next = s;
// }
// }
// /*创建一个链表(带头结点的尾插法,顺序插入)*/
// void CreateList_tail(List *head)
// {
// List p,s;
// ElementType x;
// p = (*head);
// printf("请输入要输入链表元素->");
// while(scanf("%d",&x),x!=-1)
// {
// s = (List)malloc(sizeof(ListNode));
// s->data = x;
// s->next = NULL;
// p->next = s;
// p = s;
// }
// }
// /*显示链表中元素*/
// void ShowList(List head)
// {
// List p = head->next;
// printf("链表中的元素有:");
// while(p!=NULL)
// {
// printf("%d ",p->data);
// p = p->next;
// }
// }
手撕数据结构---单链表的增删改查等操作
最新推荐文章于 2024-07-25 19:28:17 发布