链表操作

来源:互联网 发布:wps表格删除筛选数据 编辑:程序博客网 时间:2024/05/17 12:22

链表

链表是一个基本数据结构。它由一系列节点组成,每个包含任意数据字段和一个或指向下一个或以前的节点的引用(指针)。        注意:最后一个节点必须值空

比传统阵列的一个链表的主要好处是,挂钩项目的顺序可能会有所不同,在内存中或存储在磁盘上的数据项的顺序,允许项目清单进行不同的顺序遍历。

链表是一个自我指示的数据类型,因为它包含一个指针或链接到另一个相同类型的数据。链表允许在固定时间内的列表中的任何一点插入和删除节点,但不允许随机访问。

Singly-linked list    单链表

链表的最简单的一种是有每一个节点的链路的单链表(或简称SLIST )。如果它是最后一个节点,这个链接点到下一个节点列表中或为空值或空列表。

Doubly-linked list 双链表

一个更复杂的一种链表是一个双向链表或双向链表。每个节点有两个环节:如果它是第一个节点,这一个指向前一个节点,或节点指向一个空值或空列表;如果它是最后一个指向下一个节点,或节点指向一个空值或空列表节点。    由数据段和两部分指针,一部分指向前面的,一部分指向下一个节点组成。

 

Circularly-linked list   循环链表

在一个循环链表中,第一个和最后一个节点是连在一起的

 

 

 

Forexample:

 

#includestdio.h

#includemalloc.h// #include <stdlib.h>

#includestring.h

#defineN 10          //创建10个节点

typedefstruct node           //定义结构体,并为其其别名为node

{

char name[20];              //定义结构体变量字符数组name   第一部分:存放的数据段

struct node link;         //在结构体内用结构体类型的别名node声明一个指针变量link,link为结构体指针(struct node)   第二部分:节点指针

}stud;                               //结构体别名stud                                   

创建链表

stud* create(int n)    //创建有n个节点的链表,返回链表头结点  

{

stud *p,*h,*s; //h代表当前节点并指向当前节点,p代表当前节点的前一个节点,s代表当前节点的下一个节点

//stud*h =NULL//h指向当前节点(头结点)

 

//stud*s =NULL//后节点(指向创建的新节点)

 

//stud*p =NULL//p指向创建的新节点的前一个节点

  //创建头结点  stud* hh = NULL

if((h=(stud *)malloc(sizeof(stud)))==NULL)        //在堆上为stud结构体变量s申请空间     

{        //如果为NULL,则打印如下信息

printf("Memory allocation fails!");        //输出“内存分配失败!”

exit(0);                //无条件正常退出此程序的运行;exit(1)表示因错误导致程序退出

}

 

  //创建成功,初始化头结点

strcpy( h-name, “head” );        //将字符串“head”拷贝给当前节点h的name属性

h-link=NULL;                         //当前节点h的下一个节点为NULL

p=h;                                             //将h节点的内容赋值给p节点所对应的内容

 

//创建下一个节点  循环

for(int i=0;in-1;i++)

{

if((s= (stud *)malloc(sizeof(stud)))==NULL)

{

    printf("Memoryallocation fails!");

    exit(0);

}

 

//创建成功,进行初始化

printf("Please input %dperson name:", i+1);

scanf("%s",s-name);

s-link=NULL;          //给节点s的下一个节点赋值为NULL

p-link=s;                      //将s节点的内容赋值给节点p的下一个节点,即h节点

               

p=s;              //最后将节点s的内容赋值给节点P,用来代替为创建下一个节点的头的内容

   让p指向当前创建好的节点(s指向的节点)

}

return(h);       //返回当前头节点h

}

创建节点的步骤:

1、             定义变量*h(头结点),*p(指向新节点的上一个节点),*s(指向新节点)

2、             创建头结点并判断是否为空,若创建成功(不为空),初始化头结点。并把头结点h赋值给p

3、             创建下一个节点。循环语句,继续执行第二步。不再是头节点判断,当前新节点(s)判断。若创建成功(不为空),初始化新结点,并把头结点h赋值给s

4、             返回当前头结点。

 

查找元素

stud*search(stud *h, char *x) // 查询某个节点,返回链表头结点

stud *p = h;                     //定义结构体指针变量p并初始化为h,返回p

 while(p!=NULL)           //当节点p的内容不为NULL,则进行查询操作,直到p的值为NULL

{

  if(strcmp(p-name, x)==0) //头结点特殊处理(比较两个字符串name和x(当p-name=x时)。即:两个字符串自左向右逐个比较,直到出现不同的字符或遇‘\0’为止)

 return(p);                  //如果找到相同的字符,则将它返回

else                                  //否则,继续查找下一个节点

 p=p-link;              //p指向下一个节点

  }

if(p==NULL)             //如果为NULL,打印输出提示信息,没有搜索到

    printf("There is no such a student!");

return p;                                   //最后返回所查询的头节点p

}

删除元素

 stud* Delete(stud *h, char *x)    //删除某个节点,返回链表头结点h

 {

if( h == NULL)

   returnNULL;

 

/*节点h的值不为NULL,进行以下操作*/

stud * p1, *p2;        //p2 代表当前要比较的节点,p1代表当前节点的前一个节点 

p1=h;                              //将节点h的值赋值给节点p1

p2=h->link;                   //将节点h的下一个节点的值赋值给节点p2

if (strcmp( p1->name, x )== 0 )  // (如果节点p1中的值和字符x的值相同,进行释放操作)

{

      h =h->link;              //将h节点的下一个节点的值赋值给h节点

      free(p1);                   //释放节点p1点在内存中所占的空间

      returnh;                    //返回节头点h

}

else

{

        

}

while(p2!=NULL)         //当节点p2的值不为NULL时,执行以下操作

{

    if(strcmp(p2->name,x)==0)  //节点p2的值和字符x的值相同,进行释放操作

  {

           p1->link = p2->link;            //p1的下一个节点指向p2的下一个节点

           free(p2);                              //释放p2节点在内存中所占的空间

     return h;                               //返回头节点h

}

else                               //节点p2的值和字符x的值不同,则继续寻找

{

p1=p2;                  //将节点p2的值赋值给节点p1

p2=p2->link;        //将节点p2下一个的节点的值赋值给p2

}

}

rerun h;

 

插入元素

voidinsert(stud *p)   //p节点后插入一个节点

{

char stuname[20];      //定义一个字符数组

stud *s;        //声明一个指向结构体stud的指针变量s(要插入的节点s)

 

if((s= (stud *)malloc(sizeof(stud)))==NULL)  //在堆上为stud结构体变量s申请空间     

{           //如果为NULL,则打印如下信息

  printf("Memoryallocation fails!"); //输出内存分配失败

exit(0);       //无条件正常退出此程序的运行;exit(1)表示因错误导致程序退出

}

printf("Please input name” );

scanf("%s",stuname); //从键盘上输入一个字符串到stuname

strcpy(s-name,stuname); //字符串拷贝(把stuname 拷贝到s->name)

s-link=p-link;     //让节点s指向节点p的下一个节点

p-link=s;                //节点p的下一个节点指向节点s

}

释放链表

voidfreeList(stud* head) //释放链表

{     

stud* p;                                   //定义一个结构体指针变量p

while( head != NULL)     //当头节点head的内容不为NULL时就执行释放操作,直到释放完毕

   {

        p = head;                      //将头节点的值赋值给节点p

       head = head->link;       //将头节点head的下一个节点的内容赋值给头节点head

       free(p);                        //释放节点p

     }

}

打印链表

voidprintList(stud* head)       //打印链表

{     

stud* p;                                   //定义一个结构体指针变量p

p = head;                          //结构体变量整体赋值,将head的内容赋值给p

int count = 0;                   //定义整型变量 count,并初始化为0

while(p != NULL)    //如果节点p的值不为NULL,则执行打印操作,直到节点p的值为NULL

   {

         printf("%s\n", p->name);        //打印输出节点p的变量name的字符串

         p = p->link;         //将p节点的下一个节点的值赋值给节点p

count++;              //计数器加1

}

}

 

int main()

{

  int number;

char fullname[20];

stud *head,*searchpoint;

 

number=N; 

head=creat(number);

printf("Input thesrearch name:");

scanf("%s",fullname);//通过键盘输入一个字符串到fullname

searchpoint=search(head,fullname);

insert(searchpoint);

char[10] str;

scanf( “%s”, str );

head = delete( head, str );

printList( head );

freeList( head ); 

return 0;

}

 

 

 

写出程序把一个链表中的接点顺序倒排

  typedef struct linknode

  {      

int data;

struct linknode *next;

  }node;

 

链表逆置

node*reverse(node *head)

{

node *p,*q,*r; //q代表当前节点,p代表当前节点的前一个节点,r代表当前节点的下一个节点

p=head;

q=p->next;

while(q!=NULL)

{

    r=q->next;

   q->next=p;

   p=q;

   q=r;

}

head->next=NULL;

head=p;

return head;

}   

 

原创粉丝点击