您的位置:首页 > 理论基础 > 数据结构算法

数据结构学习2——单链表

2012-08-27 14:30 148 查看
顺序表的缺点:插入和删除需要进行元素的移动

链表:使用节点存储数据元素,节点的地址可以连续也可以不连续

链表分为单链表/双链表/循环链表,这次只说单链表。

单链表中一个节点的组成:数据域+指针域,指针于中存放的是是一个指针,指向下一个节点的地址。

内容包括:单链表的定义/初始化/查找节点/插入节点/删除节点

先上代码:

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

//定义单链表
struct node{
char data;
struct node *next;
};
typedef struct node linkList;

/*单链表结构
p  0x804b008
*0x804b008
data  '\0'
next  0x804b018
*0x804b018
data  'a'
next  0x804b038
*0x804b038
data  's'
next  ox804b048
*0x804b048
...
注:最后一个节点的next为NULL
*/

//初始化单链表(创建单链表)
linkList* linkListCreate()
{
char ch;
//p为创建的单链表,p2链接于p上,p1是p2与p之间的桥梁
linkList *p,*p1,*p2;
//初始化表头
p=(linkList*)malloc(sizeof(linkList));
p->data='\0';
p->next=NULL;
p1=p;//将p的首地址给p1,对p1的操作就是对p中元素的操作
while((ch=getchar())!='\n')
{
p2=(linkList*)malloc(sizeof(linkList));
p2->data=ch;
p2->next=NULL;
p1->next=p2;
p1=p2;
}
return p;//返回链表头指针
}

//查找节点:按序号查找,查找链表list中第n个节点。注:链表头的下一个节点才是第一个节点
linkList * ElemLocatebyNum(linkList *list,int n)
{
int i=0;
linkList *p;
p=list;
while(p!=NULL)
{
i++;
p=p->next;
if(n==i)
{
return p;
}
}
return NULL;
}

//查找节点:按数据元素查找,查找链表list中元素为ch的节点
linkList * ElemLocatebyVal(linkList *list,char ch)
{
linkList *p;
p=list;
while(p!=NULL)
{
p=p->next;
if(ch==p->data)
{
return p;
}
}
return NULL;
}

//插入节点:在链表list的第n个节点处插入元素ch
void linkListInsert(linkList *list,int n,char ch)
{
linkList *p,*q;
p=ElemLocatebyNum(list,n-1);//链表第n-1个节点
if(p==NULL)
{
printf("insert error!\n");
return;
}
q=(linkList*)malloc(sizeof(linkList));
q->data=ch;
q->next=p->next;
p->next=q;
}

//删除节点:删除链表list的第n个节点
void linkListDelete(linkList *list,int n)
{
linkList *p,*q;
p=ElemLocatebyNum(list,n-1);//链表第n-1个节点
//q=ElemLocatebyNum(list,n);//链表的第n个节点
if(p->next==NULL || p==NULL)
{
printf("delete error!\n");
return;
}
q=p->next;
p->next=q->next;
free(q);//释放第n个节点的内存空间
}

int main()
{
//创建链表
linkList *p,*q;
p=linkListCreate();
q=p->next;//单链表的第一个节点
printf("craete list/elment:\n");
while(q)
{
printf("%c",q->data);
q=q->next;
}
printf("\n");
//查找节点:按序号
q=ElemLocatebyNum(p,4);
printf("find node/positon 4 elment:%c\n",q->data);
//查找节点:按数据元素
q=ElemLocatebyVal(p,'j');
printf("find node/element is:%c\n",q->data);
//插入节点
linkListInsert(p,4,'Q');
q=p->next;
printf("insert node/elment:\n");
while(q)
{
printf("%c",q->data);
q=q->next;
}
printf("\n");
//删除节点
linkListDelete(p,7);
q=p->next;
printf("delete node/elment:\n");
while(q)
{
printf("%c",q->data);
q=q->next;
}
printf("\n");
return 0;
}


1.链表初始化:这里有一个链表头,用于指向链表的头节点,即链表头的下一个节点即为链表的第一个节点。理解单链表关键是要搞清楚它的存储结构,可以用工具调试看一下,我这里使用的是linux下的kDbg。在输出中输入asdfghjkl后,可以看到链表存储结构如下:



可以看到,每个节点的指针域(next指针)都指向下一个节点的首地址,最后一个节点的指针域为NULL

2.查找节点,有两种查找方式,按序号查找和按数据元素查找。

3.插入节点,一定要注意操作的先后顺序。

4.删除节点,最后一定要将删除节点的内存空间释放掉,避免造成内存泄漏。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: