结点的引入
链表是一种链式存储结构,链式存储结构的特点是用一组任意的存储单元存储数据元素。为了能正确表示数据元素之间的线性关系,需引入结点概念。一个结点表示链表中的一个数据元素,节点中除了储存数据元素的信息, 还必须存放指向下一个节点的的指针(单、双链表的最后一个节点除外,它们存储的是一个空指针NULL)
结点的结构如下图所示:
代码如下:
typedef struct node{
int data;
struct node* pNext;
}Node, *PNode;
注:这里假设结点中储存的是整型 (int) 的数据
单链表由多个结点依次连接而成,我们不难想象出它结构:
我们注意到:在第一个结点的前面多了一个头结点,这是为了处理空表的方便而引入的,它的指针指向链表的第一个结点,而它的data域不存放任何信息。
单链表的基本操作
1.创建链表
PNode createList()
{
int len, value;
PNode pHead = (PNode)(malloc(sizeof(Node)));
PNode pTail = pHead;
pTail->pNext = NULL;
printf("请输入你要的节点个数:");
scanf("%d", &len);
for(int i=1;i<=len;i++){
printf("请输入第%d个节点的值:", i);
scanf("%d", &value);
PNode pNew = (PNode)malloc(sizeof(Node));
pNew->data = value;
pTail->pNext = pNew;
pTail = pNew;
pTail->pNext = NULL;
}
return pHead;
}
2.遍历链表
void traverse(PNode pHead)
{
printf("遍历结果为:\n");
PNode pTra = pHead;
while(pTra->pNext != NULL)
{
printf("%d ", pTra->pNext->data);
pTra = pTra->pNext;
}
printf("\n");
}
3.判断链表是否为空
bool isEmpty(PNode pHead)
{
if(pHead->pNext==NULL)
return true;
else
return false;
}
4.链表长度
int length(PNode pHead)
{
int len = 0;
while(pHead->pNext!=NULL){
pHead = pHead->pNext;
len++;
}
return len;
}
5.插入结点
bool insert(PNode pHead, int pos, int val)
{
if(pos<1 || pos>length(pHead)){
return false;
}else{
PNode pInsert = pHead;
for(int i=1;i<pos;i++){
pInsert = pInsert->pNext;
}
PNode pNew = (PNode)malloc(sizeof(Node));
pNew->data = val;
pNew->pNext = pInsert->pNext;
pInsert->pNext = pNew;
return true;
}
}
6.删除结点
bool del(PNode pHead, int pos)
{
if(pos<1 || pos>length(pHead)){
return false;
}else{
PNode pDel = pHead;
for(int i=1;i<pos;i++){
pDel = pDel->pNext;
}
if(pos==length(pHead)){
free(pDel->pNext);
pDel->pNext = NULL;
}else{
PNode pNext = pDel->pNext->pNext;
free(pDel->pNext);
pDel->pNext = pNext;
}
return true;
}
}
7.查找节点
(1)按元素值查找
PNode locate(PNode pHead, int value)
{
PNode p = pHead->pNext;
while(p&&p->data!=value){ //NULL 是 0
p = p->pNext;
}
return p;
}
(2)按序号查找
PNode get(PNode pHead, int k)
{
PNode p = pHead;
for(int i=1;i<=k;i++){
p = p->pNext;
}
return p;
}
完整代码
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node* pNext;
}Node, *PNode;
PNode createList();
void traverse(PNode pHead);
bool isEmpty(PNode pHead);
int length(PNode pHead);
bool insert(PNode pHead, int pos, int val);
bool del(PNode pHead, int pos);
PNode get(PNode pHead, int k); //按序号查找
PNode locate(PNode pHead, int value);//按值查找
int main(void)
{
//test
return 0;
}
PNode createList()
{
int len, value;
PNode pHead = (PNode)(malloc(sizeof(Node)));
PNode pTail = pHead;
pTail->pNext = NULL;
printf("请输入你要的节点个数:");
scanf("%d", &len);
for(int i=1;i<=len;i++){
printf("请输入第%d个节点的值:", i);
scanf("%d", &value);
PNode pNew = (PNode)malloc(sizeof(Node));
pNew->data = value;
pTail->pNext = pNew;
pTail = pNew;
pTail->pNext = NULL;
}
return pHead;
}
void traverse(PNode pHead)
{
printf("遍历结果为:\n");
PNode pTra = pHead;
while(pTra->pNext != NULL)
{
printf("%d ", pTra->pNext->data);
pTra = pTra->pNext;
}
printf("\n");
}
bool isEmpty(PNode pHead)
{
if(pHead->pNext==NULL)
return true;
else
return false;
}
int length(PNode pHead)
{
int len = 0;
while(pHead->pNext!=NULL){
pHead = pHead->pNext;
len++;
}
return len;
}
bool insert(PNode pHead, int pos, int val)
{
if(pos<1 || pos>length(pHead)){
return false;
}else{
PNode pInsert = pHead;
for(int i=1;i<pos;i++){
pInsert = pInsert->pNext;
}
PNode pNew = (PNode)malloc(sizeof(Node));
pNew->data = val;
pNew->pNext = pInsert->pNext;
pInsert->pNext = pNew;
return true;
}
}
bool del(PNode pHead, int pos)
{
if(pos<1 || pos>length(pHead)){
return false;
}else{
PNode pDel = pHead;
for(int i=1;i<pos;i++){
pDel = pDel->pNext;
}
if(pos==length(pHead)){
free(pDel->pNext);
pDel->pNext = NULL;
}else{
PNode pNext = pDel->pNext->pNext;
free(pDel->pNext);
pDel->pNext = pNext;
}
return true;
}
}
PNode get(PNode pHead, int k)
{
PNode p = pHead;
for(int i=1;i<=k;i++){
p = p->pNext;
}
return p;
}
PNode locate(PNode pHead, int value)
{
PNode p = pHead->pNext;
while(p&&p->data!=value){ //NULL 是 0
p = p->pNext;
}
return p;
}