#include<stdio.h>
#include<malloc.h>
#include<assert.h>
typedef int ElemType;
typedef struct Node{
ElemType data;
struct Node* next;
}Node,*PNode;
typedef struct SCList{
PNode first;
PNode last;
int size;
}SCList;
void initSCList(SCList* list){
//申请空间 创建虚拟头节点
Node* node = (Node*)malloc(sizeof(Node));
assert(node != NULL);
//第一个节点 和 最后一个节点 指向虚拟头节点
list->first = list->last = node;
//虚拟头结点指向自己完成循环
node->next = node;
//当前链表大小为0
list->size = 0;
}
//申请节点
Node* malloc_node(ElemType e){
Node* node = (Node* )malloc(sizeof(Node));
assert(node != NULL);
node->next = NULL;
node->data = e;
return node;
}
//尾插
void push_back(SCList* list,ElemType e){
//申请新节点
Node* node = malloc_node(e);
//链表最后一个节点指向新节点
list->last->next = node;
//更新last指针
list->last = node;
//新节点的next指向第一个节点 形成循环
node->next = list->first;
//元素数量+1
list->size++;
}
//头插
void push_front(SCList* list,ElemType e){
//申请新节点
Node* node = malloc_node(e);
node->next = list->first->next;
list->first->next = node;
//判断当前链表是否为空
if(list->first == list->last){
//为空当前插入的节点则为last所指向的节点
list->last = node;
}
list->size++;
}
//打印链表
void show_SCList(SCList* list){
Node* p = list->first->next;
while(p != list->first){
printf("%d->",p->data);
p = p->next;
}
printf("NULL .\n last=%d,size=%d",list->last->data,list->size);
}
//删除尾部
void pop_back(SCList* list){
if(list->size == 0){
//当前链表为空
printf("当前链表为空,不可删除.\n");
return;
}
PNode p = list->first;
while(p->next != list->last){
p = p->next;
}
free(list->last);
list->last = p;
p->next = list->first;
list->size--;
}
//删除头部
void pop_front(SCList* list){
if(list->size == 0){
//当前链表为空
printf("当前链表为空,不可删除.\n");
return;
}
Node* node = list->first->next;
list->first->next = node->next;
if(list->size == 1){
//说明删除的是最后一个元素
list->last = list->first;
}
free(node);
list->size--;
}
//插入元素 [默认链表升序排序]
void insert_val(SCList* list,ElemType e){
Node* node = malloc_node(e);
Node* p = list->first;
while(p->next != list->first && p->next->data < e){
p = p->next;
}
node->next = p->next;
p->next = node;
if(node->next == list->first){
//说明插入的位置是末尾
list->last = node;
}
list->size++;
}
//查找元素
Node* find(SCList* list,ElemType key){
if(list->first == list->last){
return NULL;
}
Node* p = list->first->next;
while(p != list->first){
if(p->data == key){
return p;
}
p = p->next;
}
return NULL;
}
//返回链表长度
int length(SCList list){
return list.size;
}
//按值删除
void delete_val(SCList* list,ElemType e){
if(list->size == 0){
return;
}
Node* p = find(list,e);
if(p == NULL){
return;
}
if(p->next == list->last){
pop_back(list);
}else{
p->data = p->next->data;
p->next = p->next->next;
free(p);
list->size--;
}
}
//排序
void sort(SCList* list){
if(list->size <= 1){
return;
}
//指向第一个节点
Node* p = list->first->next;
//指向第二个节点
Node* q = p->next;
//将原链表最后一个节点指向NULL
list->last->next = NULL;
//改变last指针指向第一个节点
list->last = p;
//形成循环
p->next = list->first;
while(q != NULL){
p = q;
q = q->next;
Node* s = list->first;
//找到要插入的位置的上一个节点
while(s->next != list->first && s->next->data < p->data){
s = s->next;
}
//插入该节点
p->next = s->next;
s->next = p;
if(s->next == list->first){
//插入的位置是末尾
list->last = p;
}
}
}
//逆置链表
void reverse(SCList* list){
if(list->size <= 1){
return;
}
//指向第一个节点
Node* p = list->first->next;
//指向第二个节点
Node* q = p->next;
//将原链表最后一个节点指向NULL
list->last->next = NULL;
//改变last指针指向第一个节点
list->last = p;
//形成循环
list->last->next = list->first;
while(q != NULL){
p = q;
q = q->next;
//头插法插入节点
p->next = list->first->next;
list->first->next = p;
}
}
//清空链表
void clear(SCList* list){
Node* p = list->first->next;
while(p != list->first){
list->first->next = p->next;
free(p);
p = list->first->next;
}
list->last = list->first->next = list->first;
list->size = 0;
}
//销毁链表
void destroy(SCList* list){
clear(list);
free(list->first);
list->first = list->last = NULL;
}
int main(){
SCList list;
initSCList(&list);
int select = 1;
ElemType item = 0;
while(select){
printf("\n");
printf("***********************************\n");
printf("* [1] push_back [2] push_front *\n");
printf("* [3] show_list [4] pop_back *\n");
printf("* [5] pop_front [6] insert_val *\n");
printf("* [7] find [8] length *\n");
printf("* [9] delete_val [10] sort *\n");
printf("* [11] reverse [12] clear *\n");
printf("* [13] destroy [0] exit_system *\n");
printf("***********************************\n");
printf("请选择> ");
scanf("%d",&select);
if(!select){
break;
}
PNode p = NULL;
switch(select){
case 1:
printf("请输入要输入的数据(-1结束):>");
while(scanf("%d",&item),item != -1){
push_back(&list,item);
}
break;
case 2:
printf("请输入要输入的数据(-1结束):>");
while(scanf("%d",&item),item != -1){
push_front(&list,item);
}
break;
case 3:
show_SCList(&list);
break;
case 4:
pop_back(&list);
break;
case 5:
pop_front(&list);
break;
case 6:
printf("请输入要插入的数据:>");
scanf("%d",&item);
insert_val(&list,item);
break;
case 7:
printf("请输入要查找的数据:>");
scanf("%d",&item);
p = find(&list,item);
if(p == NULL){
printf("查找的数据不存在.\n");
}
break;
case 8:
printf("该链表长度为: %d.\n",length(list));
break;
case 9:
printf("请输入要删除的数据:>");
scanf("%d",&item);
delete_val(&list,item);
break;
case 10:
sort(&list);
break;
case 11:
reverse(&list);
break;
case 12:
clear(&list);
break;
case 13:
destroy(&list);
break;
}
}
destroy(&list);
return 0;
}