数据结构学习
单链表的学习
注:以下结点的数据域均为char类型
1.链表的结点是由数据域和指针域两部分组成,
typedef struct LNode
{
char data;
struct LNode *next;
}LNode;
2.头节点:是开始节点之前的节点,可有可无,其数据域不包含任何信息。
3.开始节点:第一个元素所在的节点
4.头指针(head):(指针的概念就是一个指向的过程)永远指向链表中第一个节点的位置(如果链表有头节点,那么头指针就指向头节点,否则就指向开始节点)
5.单链表
分类如下:
(1)带头节点单链表:head指向头节点,head始终不等于NULL,当head->next等于NULL的时候链表为空。
(2)不带头节点单链表:head指向开始节点,当head=NULL时,链表为空
6.头指针和头结点的区别,头指针只是声明但是不会赋予内存空间,但时头结点,是需要声明并且赋予内存空间,包含数据域和指针域
单链表的应用
1.单链表节点的声明
typedef struct LNode
{
char data;
struct LNode *next;
}LNode;
2.单链表的创建
有头插法和尾插法两种
头插法:
LNode *HeadCreateList(int len)
{
LNode *L=(LNode*)malloc(sizeof(LNode));
LNode *tmp=L;
tmp->next =NULL;//此时L链表只有一个头结点;
for(int i=1:i<len;i++)
{
LNode *p=(LNode*)malloc(sizeof(LNode));
scanf("%c",&p->data);
//核心代码
p->next=tmp->next;
tmp->next=p;
}
return (Lnode*)L;
}
尾插入法:
LNode *TailCreateList(int len)
{
LNode *L=(LNode*)malloc(sizeof(LNode));
LNode *tmp=(LNode*)malloc(sizeof(LNode));
tmp=L;
tmp->next=NULL;
for(int i=1,i<len;i++)
{
LNode *p=(LNode*)malloc(sizeof(LNode));
scanf("%c",&p->data);
//核心代码
tmp->next=p;
tmp=p
}
tmp->next=NULL
return (LNode*)L;
}
要点:一定要心中要明白尾插法和头插法的实现过程,进而去理解两种方法(时间复杂度和空间复杂度的问题)
3.链表中查找某个结点
因为链表不像数组那样支持随机访问,链表的存取方式是顺序存取的,因此需要通过遍历的方法进行查找,例如需要找到第5个结点,必须先遍历走完1-4结点,才能得到第5个结点。代码如下:
int Search(LNOde *L,char elem)
{
LNOde *tmp=L;
int pos=0;
int i=1;
while(tmp->next)
{
tmp=tmp->next;
if(elem=temp->data)
{
pos=i;
return pos;
}
i++
}
return ERROR;
}
4.修改某个结点的数据域
LNode *Replace(LNode *L,int pos,char elem)
{
LNode *tmp=(LNode*)malloc(sizeof(LNode))//tmp实际上只是一个结点
tmp=L;
tmp=tmp->next;
for(int i=1;i<pos;i++)
{
tmp=tmp->next;
}
tmp->data=elem;
return (LNode*)L;
}
5.往链表中插入结点(联想手拉手):
插入结点三种位置:
(1)链表首部:头结点和开始结点之间位置
(2)链表中间
(3)链表尾部
三种位置的插入方式都是一样的
代码如下:
LNode *InsertList(LNode *L,int pos,char elem)
{
LNode *tmp=L;
int i=0;
while((tmp!=NULL)&&(i<pos-1))
{
tmp=tmp->next;
i++;
}
LNode *New;
New->data=elem;
New->next=tmp->next
tmp->next=New;
return (LNode*)L;
}
6.删除链表中的结点
注:删除某个结点,需要将其摘下来,同时将这一结点的前后两个结点连接起来,同时要释放被删除结点的内存
代码如下:
LNode *DeleteList(LNode *L,int pos,int *elem)
{
LNode *tmp=L;//引入中间变量tmp,用于循环链表
int i=0;
/*首先找到删除结点的上一个结点,即第pos-1个结点*/
while((tmp!=NULL)&&(i<pos-1))
{
tmp=tmp->next;
++i;
}
if((tmp==NUll)||(i>pos-1))
{
printf("%s:Delete false!\n",_FUNCTION_);
return (LNode*)tmp;
}
LNode *del=tmp->next;//使del等于被删除结点
*elem = del->data;
tmp->next=del->next;
free(del);//释放被删除结点的内存
del=NULL;//将被删除结点的指针指向NULL
return (LNode*)L;
}
全部代码:
#include<stdio.h>
#include<stdlib.h>
#define ERROR 1
#define OK 0
/*定义一个链表的结点*/
typedef struct LNode
{
char data
struct LNode *next
}LNode;
//操作函数的声明
LNode *HeadCreateList(int len);
LNode *TailCreateList(int len);
char SearchList(LNode *L,char elem);
LNode *Replace(LNode *L,int pos,char elem);
LNode *Insert(LNode *L,int pos,char elem);
LNode *Delete(LNode *L,int pos,char elem);
void PrintList(LNode *L)
//测试函数声明
void test1(LNode *L);//search function
void test2(LNode *L);//replace
void test3(LNode *L);//insert
void test4(LNode *L);//delete
LNode *test5(void);//headcreatelist
LNode *test6(void);//tailcreatelist
int main()
{
int len=0;
int cmd;
LNode *L;
printf("please input listlengh:");
scanf("%d",&len);
L=TailCreateLise(len);
PrintList(L);
while(1)
{
cmd =MenuSelect();
switch(cmd)
{
case 1:test1(L);
case 2:test2(L);
case 3:test3(L);
case 4:test4(L);
case 5:L=test5();
case 6:L=test6();
case 7:system("cls");break;//clear screen
case 8:exit(0);
break;
}
}
return 0;
}
LNode *HeadCreateList(int len)
{
LNode *L=(LNode*)malloc(sizeof(LNode));
LNode *tmp=L;
tmp->next=NULL;
for(int i=1;i<len;i++)
{
LNode *p=(LNode*)malloc(sizeof(LNode));
scanf("%c",$p->data);
p->next=tmp->next;
tmp->next=p;
}
return (LNode*)L;
}
LNode *TailCreateList(int len)
{
LNode *L=(LNode*)malloc(sizeof(LNode));
LNode *tmp=L;
for(i=1;i<len;i++)
{
LNode *p=(LNode*)malloc(sizeof(LNode));
scanf("%c",&p->data);
tmp->next=p;
tmp=p;
}
tmp->next=NULL;//this step is vailable to set the end of point is NULL;
return (LNode*)L;
}
char SearchList(LNode *L,char elem);
{
LNode *tmp=L;
int pos=0;
int i=1;
while(tmp->next)
{ tmp=tmp->next;
if(elem==tmp->data)
{
pos=i;
printf("the %c position in the list is %d\n",elem,pos);
return pos;
}
i++;
}
printf("search error!\n");
return ERROR;
}
LNode *Replace(LNode *L,int pos,char elem)
{
for(int i=1;i<pos,i++)
{
tmp=tmp->next;
}
tmp->data=elem;
return (LNode*)L;
}
LNode *Insert(LNode *L,int pos,char elem)
{
LNode*tmp=L;
int i=0
while((tmp!=NULL)&&(i<pos-1))
{
tmp=tmp->next;
i++
}
if((tmp==NULL)||(i>pos-1))//NULL list and the zero position are not inserted
{
return (LNode*)tmp;
}
LNode *p=(LNode*)malloc(sizeof(LNode));
p->data=elem;
p->next=tmp->next;
tmp->next=p;
return (LNode*)L;
}
LNode *Delete(LNode *L,int pos,char elem)
{
LNode *tmp=L;
while((tmp!=NULL)&&(i<pos-1))
{
tmp=tmp->next;
i++;
}
if((tmp==NULL)||(i>pos-1))
{
return (LNode*)tmp;
}
LNode *p=(LNode*)malloc(sizeof(LNode));
p->data=elem;
p=tmp->next;
tmp->next=temp->next->next;
free(p)
p=NULL;
return (LNode*)L;
}
void PrintList(LNode *L)
{
LNode *tmp=L;
int count=0;
while(tmp->next!=NULL)
{
tmp=tmp->next;
print("%c",tmp->data);
count++
if(count%10==0)
{
printf("\n");//没10个数据一行
}
}
}
int MenuSelect(void)
{
int cmd;
printf("1.Search test\n");
printf("2.Replace test\n");
printf("3.Insert test\n");
printf("4.Delete test\n");
printf("5.TailCreateList test\n");
printf("6.HeadCreateList test\n");
printf("7.Clear\n");
printf("8.Exit\n");
do
{
printf("Enter your choice:");
scanf("%d",&cmd);
}while(cmd<0||cmd>8);
return cmd;
}
void test1(LNode *L)
{
printf("please input your search elem:\n");
scanf("%c",&elem);
SearchList(L,elem);
}
void tes2(LNode *L)
{ PrintList(L);
int pos;
char elem;
printf("please input replace position:");
scanf("%d",&pos);
printf("please input replace elem:");
scanf("%c",&elem);
L=Replace(L,pos,elem);
PrintList(L);
}
void test3(LNode *L);
{
PrintList(L);
int pos;
char elem;
printf("please input insert position:");
scanf("%d",&pos);
printf("please input insert elem:");
scanf("%c",&elem);
L=Insert(L,pos,elem);
PrintList(L);
}
void test4(LNode *L)
{
PrintList(L);
int pos;
char elem;
printf("please input delete position:");
scanf("%d",&pos);
printf("please input delete elem:");
scanf("%c",&elem);
L=Delete(L,pos,elem);
PrintList(L);
}
LNode *test5()
{
LNode *L;
printf("please input listlengh:");
scanf("%d",&len);
L=HeadCreateList(len);
PrintList(L);
return (LNode*)L;
}
LNode *test6()
{
LNode *L;
printf("please input listlengh:");
scanf("%d",&len);
L=TailCreateList(len);
PrintList(L);
return (LNode*)L;
}
总结:学习数据结构中的链表一定要明白单链表的原理,需要更加了解指针的概念