#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct Node {
int data;
struct Node * pNext;
}NODE,* PNODE; //NODE 等价于 struct Node * PNODE等价于 struct Node *
PNODE create_list(void);
void traverse(PNODE);
void sort(PNODE);
bool is_empty(PNODE);
int length_list(PNODE);
bool insert_before(PNODE,int ,int );
bool delete_list(PNODE ,int ,int * );
void sort(PNODE);
int main(void){
PNODE pHeader =NULL;
pHeader=create_list();
//traverse(pHeader);
sort(pHeader);
traverse(pHeader);
//printf("%d",length_list(pHeader));
return 0;
}
PNODE create_list(void){ //创建一个非循环单链表
int length,i,val;
printf("请输入需要生成的链表的个数lenth=");
scanf("%d",&length);
printf("\n");
//首先创建一个头节点
PNODE pHeader =NULL;
pHeader=(PNODE)malloc(sizeof(NODE));
PNODE pTail=pHeader; //既是头节点,也是尾节点
pTail->pNext=NULL; //默认尾节点的指针域为空
for(i=0;i<length;i++){
printf("请输入第%d个元素的值val=",i+1);
scanf("%d",&val);
PNODE pNew=(PNODE)malloc(sizeof(NODE)); //每次循环生成一个新节点
//每次生成的节点都应该挂到链表的最后一个节点,也就是尾节点,不能是头结点;
//解决办法,定义一个尾节点指针变量,开始尾节点等于头节点,每生成一个节点,这个新节点就是尾节点
// 每次把生成的节点挂到尾节点上;
pNew->data=val; //把输入的值赋给节点的值
pNew->pNext=NULL; //将新节点的指针域指向空
pTail->pNext=pNew; //将新节点挂到尾节点上
pTail=pNew; //将尾节点变成新创建的节点,这样每次生成的节点都是尾节点,可以很巧妙的解决问题
}
return pHeader;
}
void traverse(PNODE pHeader){
int i=0;
while(pHeader->pNext!=NULL){
i++;
printf("第%d个节点的值是%d\n",i,pHeader->pNext->data);
pHeader=pHeader->pNext; //每次将头节点的指针域向后移动
}
// int i=0;
// PNODE p=pHeader->pNext;
// while(p!=NULL){
// i++;
// printf("第%d个节点的值是%d\n",i,p->data);
// p=p->pNext; //每次将头节点的指针域向后移动
// }
}
//判断是否为空
bool is_empty(PNODE pHeader){
if(NULL==pHeader->pNext){
printf("链表为空\n");
return true;
}
return false;
}
//求链表的长度
int length_list(PNODE pHeader){
int i=0;
while(pHeader->pNext!=NULL){
i++;
pHeader=pHeader->pNext;
}
return i;
}
//指定位置插入
bool insert_before(PNODE pHeader,int pos,int val) {
int i=0;
PNODE p= pHeader;
while(p!=NULL&&i<pos-1){ //退出while循环后,i的值变为pos
p=p->pNext; //p最后指向的是pos位置的节点
i++;
}
if(i>pos-1||p=NULL){
return false;
}
PNODE pNew=(PNODE)malloc(sizeof(NODE));
if(PNew==NULL){
printf("动态内存失败\n");
exit(-1);
}
pNew->data=val; //将值赋值给新节点
PNODE q=p->pNext; //将p指向的节点地址赋值给q
p->pNext=pNew; //将p指向新节点
pNew->pNext=q; //将 新节点指向q
return true;
}
//删除
bool delete_list(PNODE pHeader,int pos,int * val){
int i=0;
PNODE p= pHeader;
while(p!=NULL&&i<pos-1){
p=p->pNext;
i++;
}
if(i>pos-1||p=NULL){
return false;
}
pNode q=p->pNext;
*val=p->data;
//删除p节点后面的节点
p->pNext=p->pNext->pNext;
free(q);
q=NULL;
return true;
}
//排序
//链表广义来说它和数组是一样的,都是线性结构,那么他们的排序算法也是一样的,只是具体的实现细节有差异
//因此,链表的排序可以参照数组的排序
void sort(PNODE pHeader){
//数组排序
// int i,j,t;
// for(i=0;i<length-1;i++){
// for(j=i+1;j<length;j++){
// if(a[i]>a[j]){
// t=a[i];
// a[i]=a[j];
// a[j]=t;
// }
// }
// }
//链表排序
int i,j,t;
PNODE p,q;
int length=length_list(pHeader);
// i=0;数组第1个有效元素,对应p=pHeader->pNext 也就是链表中第一个有效元素的地址; i++ 对应p->pNext
//j=i+1对应q=q->p->PNext; j++ 对应q=q->pNext
// a[i] 表示下标
for(i=0,p=pHeader->pNext;i<length-1;i++,p=p->pNext){
for(j=i+1,q=p->pNext;j<length;j++,q=q->pNext){
if(p->data>q->data){ //相当于数组的 if(a[i]>a[j]){ a[i]>a[j]
t=p->data; //相当于数组的 t=a[i];
p->data=q->data; //相当于数组的 a[i]=a[j];
q->data=t; //相当于数组的 a[j]=t;
}
}
}
return ;
}