您的位置:首页 > 其它

链表的基础操作总结(链表创建,插入,删除,遍历等等)

2013-09-14 19:54 597 查看
直接上代码吧,感觉注释还可以,应该可以看的懂。。不懂的话。。

就再看看吧。。。

// 数据结构基础--链表的创建及链表基本操作

#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 creat_list(void) ;                              // 创建链表
void traverse_list(PNODE phead) ;					  // 遍历输出链表
bool is_empty(PNODE pHead) ;						  // 判断链表是否为空
int length_list(PNODE pHead) ;						  // 求链表长度
bool insert_list(PNODE pHead, int pos, int val) ;	  // 插入链表元素
bool delete_list(PNODE pHead, int pos, int *) ;		  // 删除链表元素
void sort_list(PNODE pHead) ;						  // 对链表进行排序

/**********************************/
// 主函数
/**********************************/
int main()
{
PNODE pHead = NULL ;  // 等价于struct Node* pHead = NULL ;
int val, pos, ele ;

pHead = creat_list() ; // creat_list(), 创建一个非循环链表

if (is_empty(pHead))
{
printf("链表为空!长度为0 。\n") ;
}
else
{
printf("链表不为空!其长度为%d。\n\n", length_list(pHead)) ;
printf("您所创建的链表是:\n") ;
traverse_list(pHead) ;  // 遍历该链表
printf("\n") ;
}

printf("对该链表从大到小排序后为:\n") ;
sort_list(pHead) ;
traverse_list(pHead) ;

printf("\n您是否要对该链表插入元素:(y/n) \n") ;
char ch;
printf("Please enter:") ;
getchar() ;
scanf("%c" , &ch) ;
printf("%c\n", ch) ;
if (ch == 89 || ch == 121)
{
printf("输入您要插入的元素及位置(以逗号隔开):") ;
scanf("%d,%d", &pos, &ele) ;
insert_list(pHead, pos, ele) ;
printf("插入元素后该链表为:\n") ;
traverse_list(pHead) ;
}
else
{
printf("您选择不插入数据!") ;
}

printf("\n请输入您要删除的元素位置:\n") ;
scanf("%d", &pos) ;
if (delete_list(pHead, pos, &val))
{
printf("删除成功,您删除的元素是%d。\n", val) ;
printf("删除后的链表为:\n") ;
traverse_list(pHead) ;
}

return 0 ;
}

/**********************************/
// 创建链表调用函数
/**********************************/
PNODE creat_list(void)           // 该函数为PNODE类型的,即是其返回值PNODE类型的,即是一个地址
{
int len ;  // 用来存放有效节点的初始个数
int i ;
int val ;  // 用来临时存放用户输入的节点的值

PNODE pHead = (PNODE) malloc(sizeof(NODE)) ;   // 分配内存空间,创建链表
if ( pHead == NULL)
{
printf("内存分配失败,程序将终止!\n") ;
exit(-1) ;
}

PNODE pTail = pHead ;
pTail ->pNext = NULL ;

printf("请输入您要生成的链表节点数:len=") ;
scanf("%d" , &len) ;

for (i = 0; i<len; ++ i)
{
printf("请输入第%d个节点值:", i+1) ;
scanf("%d", &val) ;
printf("\n") ;

PNODE 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 traverse_list(PNODE phead)
{
PNODE p = phead->pNext ;
while (p != NULL)
{
printf("%d\t", p->data) ;
p = p->pNext ;
}
printf("\n") ;

}

/**********************************/
// 判断链表是否为空调用函数
/**********************************/
bool is_empty(PNODE pHead)
{
if ( pHead->pNext == NULL)    // 头结点指针域为空,则链表为空
{
return true ;
}
else
{
return false ;
}
}

/**********************************/
// 求链表长度调用函数
/**********************************/
int length_list(PNODE pHead)
{
int len = 0 ;
PNODE p = pHead ->pNext ;
while ( p != NULL)
{
++ len ;
p = p->pNext ;
}
return len ;
}

/**********************************/
// 对链表排序调用函数--从大到小
/**********************************/
void sort_list(PNODE pHead)
{
int i, j , t;
int len = length_list(pHead) ;
PNODE p, q ;
// 类似于数组的冒泡排序--完全同质
for (i =0, p = pHead->pNext; i<len-1; ++i, p = p->pNext)
{
for (j =i+1, q = p->pNext; j<len ; ++j, q = q->pNext)
{
if (p->data < q->data)
{
t = p->data ;
p->data = q->data ;
q->data = t ;
}
}
}
return ;
}

/**********************************/
// 对链表插入元素调用函数
/**********************************/
/*
插入元素的原理:
if you want to insert an element to this 链表。The first thing you have to do is 把这个要插入的位置腾出来。
即是必须创建一个新的链表元素,而且是自由的链表元素---等待安排。
并且有一个新的链表指针,指向(如何使其指向亦是一个值得思考的问题)要插入的位置的前面---监视该位置,留待后用。
然后,用你所创建那个自由的链表元素插入。
插入的前提是将目标链表截成两端--从要插入的位置前面截断,最后用挂靠的方式链接即可。
其原理是---p->next 所代表的是一个地址,也可以认为是下一个链表元素
关于自由链表元素--其data域用于存储要插入的元素值。
此时还需要创建一个临时的链表元素,用于临时存储地址。

具体如下:
pNew -> data = val ;   // 自由元素数据域
PNODE q = p->next ;    // 临时元素存储pos位置的地址
p->next = pNew ;       // 将自由元素的地址赋值给监视元素的地址域--挂到监视元素后面
pNew->next = q ;       // 将临时元素--即是原来pos位置元素    的地址赋值给自由元素--挂到自由元素后面

此时就完成整个链接--将插入的元素挂到其前面的那个元素后面,再将原来后半部分的元素挂到新插入的元素后面

*/
bool insert_list(PNODE pHead, int pos, int val)
{
int i = 0 ;
PNODE p = pHead ;

while(p != NULL && i<pos-1)
{
p = p->pNext ;
++i ;
}

if (i>pos-1 || p==NULL)
{
return false ;
}

PNODE pNew = (PNODE)malloc(sizeof(NODE)) ;
if (pNew == NULL)
{
printf("动态内存分配失败!") ;
exit(-1) ;
}
pNew -> data = val ;   // 自由元素数据域
PNODE q = p->pNext ;    // 临时元素存储pos位置的地址
p->pNext = pNew ;       // 将自由元素的地址赋值给监视元素的地址域--挂到监视元素后面
pNew->pNext = q ;       // 将临时元素--即是原来pos位置元素的地址赋值给自由元素--挂到自由元素后面
// 此时完成链表的重新链接
return true ;

}

/**********************************/
// 对链表删除元素调用函数
/**********************************/
bool delete_list(PNODE pHead, int pos, int *val)
{
int i = 0 ;
PNODE p = pHead ;

while(p->pNext != NULL && i<pos-1)
{
p = p->pNext ;
++i ;
}

if (i>pos-1 || p->pNext==NULL)
{
return false ;
}

PNODE q = p->pNext ;
*val = q->data ;

p->pNext = p->pNext->pNext ;
free(q) ;               // 释放内存!!!
q=NULL ;

return true ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐