前言
本文记录的是链表的一些操作,例如链表的创建、排序、删除、求链表的长度、判断链表是否为空。以下内容是根据郝斌老师教导所写的代码。
一、代码
代码仅供参考,若有不足的地方,欢迎在评论区一起讨论。
#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 CreateList(); //创建链表,返回值是一个头结点指针
void TraverseList(PNODE head); //遍历链表
bool Is_Empty( PNODE phead ); //判断链表是否为空
int Length_List( PNODE phead ); //求链表的长度
void Sort_List( PNODE phead ); //链表排序
bool Insert_List(PNODE phead, int pos, int val ); //链表在pos位置前插入新元素,pos是从1开始的
bool Delete_List(PNODE phead, int pos, int* val); //删除pos位置的节点,pos从1开始i
int main(void) {
int val, pos;
PNODE phead = NULL; //头结点先指向空
phead = (PNODE)malloc( sizeof( NODE ) );
if( NULL == phead ) {
printf("创建链表失败!\n");
exit(-1);
}
phead = CreateList(); //phead得到创建链表的头结点
printf("该链表是:");
TraverseList(phead); //遍历链表
if( Is_Empty( phead ) ) {
printf("该链表为空\n");
} else {
printf("该链表不为空\n");
}
int len = Length_List( phead );
printf("链表的长度是:%d\n", len);
printf("该链表排序后:");
Sort_List( phead );
TraverseList(phead); //遍历链表
printf("\n");
printf("请输入您想要在哪个位置前插入节点和插入节点的值:");
scanf("%d,%d", &pos, &val);
printf("\n");
Insert_List(phead, pos, val);
printf("插入后链表变成:");
TraverseList(phead); //遍历链表
if(Delete_List(phead, 5, &val) ) {
printf("删除链表第五个节点成功!\n");
}
printf("删除后链表为:");
TraverseList(phead); //遍历链表
printf("\n");
return 0;
}
//尾插法
PNODE CreateList(){
int len, val, i; //len是链表的长度,val是节点的值
PNODE phead = NULL; //头结点先指向空
phead = (PNODE)malloc( sizeof( NODE ) );
if( NULL == phead ) {
printf("创建链表失败!\n");
exit(-1);
}
PNODE ptail = phead;
ptail->pNext = NULL; //有可能一个节点都没有
printf("请输入您要创建多少个节点的链表:");
scanf("%d", &len);
for( i = 0; i < len; i++ ) {
printf("请输入第%d个节点的值:", i + 1);
scanf("%d", &val);
PNODE pnew;
pnew = (PNODE)malloc( sizeof(NODE) );
if( NULL == pnew ){
printf("创建新节点失败!\n");
exit(-1);
}
pnew->data = val;
ptail->pNext = pnew;
pnew->pNext = NULL;
ptail = pnew;
}
return phead;
}
//遍历链表
void TraverseList(PNODE phead){
PNODE p;
p = phead->pNext;
while( NULL != p ){
printf("%d ", p->data);
p = p->pNext;
}
printf("\n");
}
//判断链表是否为空
bool Is_Empty( PNODE phead ) {
if( NULL == phead ) {
return true;
} else {
return false;
}
}
//求链表的长度
int Length_List( PNODE phead ) {
PNODE p = phead->pNext;
int len = 0;
while( NULL != p ) {
len++;
p = p->pNext;
}
return len;
}
//链表的由小到大排序(冒泡法)
void Sort_List( PNODE phead ) {
int i, j, temp, len;
len = Length_List(phead);
PNODE p, q;
for( j = 0, p = phead->pNext; j < len-1; j++, p = p->pNext) {
for( i = 0, q = phead->pNext; i < (len-1)-j; i++ , q = q->pNext ){
if( q->data > q->pNext->data ){
temp = q->data;
q->data = q->pNext->data;
q->pNext->data = temp;
}
}
}
return ;
}
//链表的插入,在phead所指向的链表的第pos个节点的前面插入一个新的节点,该节点的值是val,并且的pos的值是从1开始
bool Insert_List(PNODE phead, int pos, int val ) {
int i = 0;
PNODE p = phead;
//让p指向链表的pos位置的前一个节点
while( (NULL != p) && (i < pos-1) ) {
p = p->pNext; //指向下一个节点
i++;
}
if( (i > pos-1) || (NULL == p) ) {
return false;
}
PNODE pnew = (PNODE)malloc( sizeof(NODE) );
if( NULL == pnew) {
printf("创建新节点失败!\n");
exit(-1);
}
pnew->data = val;
PNODE q = p->pNext; //此时p指向第pos个节点的前一个节点,q指向p的下一个节点
p->pNext = pnew;
pnew->pNext = q;
return true;
}
//删除pos位置的节点,pos从1开始
bool Delete_List(PNODE phead, int pos, int* val) {
int i = 0;
PNODE p = phead;
//让p指向链表pos的前一个节点
while( (NULL != p->pNext) && (i < pos-1) ) {
i++;
p = p->pNext;
}
if( (i > pos-1) || (NULL == p->pNext) ) {
return false;
}
PNODE q = p->pNext;
*val = q->data;
printf("被删除的节点的值是:%d\n", *val);
//删除p节点的后一个节点
p->pNext = p->pNext->pNext;
free(q);
q = NULL;
return true;
}
二、结果所示
总结
一些基本算法需要不断在用笔在纸上不断画图推敲,验证自己所写的代码是否有误。学习数据结构,光看伪算法而不上机操作是无法提升水平。