(转)一个简单的带头尾指针单向链表(C实现)

用C写了一个带头尾指针的单向链表,仅在尾部进行插入操作,在任意位置进行删除操作。因为只用到这么些功能,又因为懒,所以没有扩展。因为插入是固定在尾部进行,带一个尾指针的好处是显而易见的。当然删除时要付出一些开销。
  list.h
  -------------------------------------------
  /* list.h
  ** Copyright 2004 Coon Xu.
  ** Author: Coon Xu
  ** Date: 06 Sep 2004
  */
  #ifndef LIST_H
  #define LIST_H
  #include <stdio.h>
  #include <stdlib.h>
  struct listnode
  {
   struct listnode* next;
   int data;
  };
  struct list
  {
   struct listnode* head;
   struct listnode* tail;
   int count;
  };
  void list_init(struct list*);
  void list_insert(struct list*, struct listnode*);
  int list_delete(struct list*, struct listnode*);
  #endif
  ------------------------------------------
  list.c
  ------------------------------------------
  /* list.c
  ** Copyright 2004 Coon Xu.
  ** Author: Coon Xu
  ** Date: 06 Sep 2004
  */
  #include "list.h"
  void list_init(struct list* myroot)
  {
   myroot->count = 0;
   myroot->head = NULL;
   myroot->tail = NULL;
  }
  void list_insert(struct list* myroot, struct listnode* mylistnode)
  {
   myroot->count++;
  
   mylistnode->next = NULL;
   if(myroot->head == NULL)
   {
   myroot->head = mylistnode;
   myroot->tail = mylistnode;
   }
   else
   {
   myroot->tail->next = mylistnode;
   myroot->tail = mylistnode;
   }
  }
  int list_delete(struct list* myroot, struct listnode* mylistnode)
  {
   struct listnode* p_listnode = myroot->head;
   struct listnode* pre_listnode;
  
   //myroot is empty
   if(p_listnode == NULL)
   {
   return 0;
   }
  
   if(p_listnode == mylistnode)
   {
   myroot->count--;
   //myroot has only one node
   if(myroot->tail == mylistnode)
   {
   myroot->head = NULL;
   myroot->tail = NULL;
   }
   else
   {
   myroot->head = p_listnode->next;
   }
   return 1;
   }
  
   while(p_listnode != mylistnode && p_listnode->next != NULL)
   {
   pre_listnode = p_listnode;
   p_listnode = p_listnode->next;
   }
   if(p_listnode == mylistnode)
   {
   pre_listnode->next = p_listnode->next;
   myroot->count--;
   return 1;
   }
   else
   {
   return 0;
   }
  
  }
  -------------------------------------------
  main.c
  -------------------------------------------
  #include <stdio.h>
  #include <stdlib.h>
  #include "list.h"
  int main(int argc, char *argv[])
  {
   struct list l;
   list_init(&l);
   int ix = 0;
  
   for(ix = 0; ix < 10; ix++)
   {
   struct listnode* p_node = malloc(sizeof(struct listnode));
   p_node->data = ix;
   list_insert(&l, p_node);
   }
  
   struct listnode* p_listnode = l.head;
   while(p_listnode != NULL)
   {
   printf("%d/n", p_listnode->data);
   p_listnode = p_listnode->next;
   }
  
   int input;
   printf("input the number you want delete:/n");
   scanf("%d", &input);
  
   while(input > 0)
   {
   p_listnode = l.head;
   while(p_listnode->next != NULL && p_listnode->data != input)
   {
   p_listnode = p_listnode->next;
   }
  
   if(p_listnode->data == input)
   {
   printf("Delete success!!/nprint the list!!/n");
   list_delete(&l, p_listnode);
   free(p_listnode);
   p_listnode = l.head;
   while(p_listnode != NULL)
   {
   printf("%d/n", p_listnode->data);
   p_listnode = p_listnode->next;
   }
   }
   else
   {
   printf("not find %d/n", input);
   }
   scanf("%d", &input);
   }
   system("PAUSE");
   return 0;
  }

 

============================================================================

抄了一遍,还是要多动手啊。

============================================================================

#include "list.h"
#define debug(fmt, arg...) printf("%d@%s"fmt"/n",__LINE__,__FUNCTION__,##arg);

void list_insert(struct list *myroot, struct listnode *plistnode)
{
 struct listnode *ph  = myroot->head; 
 struct listnode *pt  = myroot->tail; 
 struct listnode *ptp = myroot->head; 

 if(ph == pt) 
 {
  debug();
  ph->next = plistnode;
  pt = plistnode;
  myroot->tail = pt;
  myroot->count ++;
  pt->next = NULL;
 }
 else
 {
  debug();
  pt->next = plistnode;
  pt = pt->next;
  myroot->tail = pt;
  myroot->count ++;
  pt->next = NULL;  
 }
 
}

void list_init(struct list *myroot)
{
 myroot->count = 0; 
 myroot->head  = myroot;
 myroot->tail  = myroot;
}

int list_delete(struct list *myroot, struct listnode *plistnode)
{
 struct listnode *pre = myroot->head;
 struct listnode *pc = myroot->head;

 printf("/ncurrent count is %d/n",myroot->count);
 
 if(plistnode == NULL)
  printf("/nwrong node type/n");
 if(myroot->head == myroot->tail)
  printf("/n the list has all deleted yet/n");

 while(pc != plistnode && pc->next != NULL)
 {
  debug();
  pre = pc;
  pc  = pc->next;
 } 
 if(pc->next == NULL && plistnode != pc)
 {
  printf("/nnode doesn't exsit/n");
  return -1;
 }
 else
 {
  debug();
  printf("/nnode deleted success/n");
  pre->next = pc->next;
  myroot->count --;
  free(plistnode);
 }
 
 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 如果使用带头尾指针单向链表表示一个堆栈,那么栈顶指针top应该指向链表的头节点,即top = head->next。这是因为堆栈的特点是后进先出,每次插入元素都是在链表头部插入,因此最后插入的元素就在链表头部,也就是栈顶。而链表的头节点是不存储数据的,它的作用是方便链表的操作,因此栈顶指针应该指向头节点的下一个节点。 ### 回答2: 采用带头尾指针单向链表表示一个堆栈,可以将头指针指向链表的头节点,尾指针指向链表的尾节点。栈顶指针top可通过头指针进行设置。 在入栈操作时,可以将新元素插入到头节点之后,然后将栈顶指针top指向新插入的节点即可。此时,栈顶指针top指向的节点即为最新插入的元素,即为栈顶元素。 在出栈操作时,可以将栈顶元素的下一个节点设置为新的头节点,然后将栈顶指针top指向新的头节点即可。此时,栈顶指针top指向的节点即为出栈后新的栈顶元素。 栈顶指针top的设置可以简化入栈和出栈操作的实现。通过头指针操作链表的头节点,可以方便地进行元素的插入和删除操作,并且操作的时间复杂度都为O(1)。此外,栈顶指针top的设置还可以提高堆栈的效率,使得栈的操作更加高效。 ### 回答3: 若采用带头尾指针单向链表表示一个堆栈,堆栈的栈顶指针top应该指向链表尾指针。这是因为加入新的元素时,需要将元素插入链表的尾部,而出栈操作时,需要删除链表的尾部元素。通过将top指针指向尾指针,可以方便地实现元素的插入和删除操作。 在初始状态下,若链表为空,则top指针为空。当执行入栈操作时,top指针始终指向链表的尾部元素,即指向最新入栈的元素。当执行出栈操作时,删除链表的尾部元素后,top指针需要更新为指向删除后的新的尾部元素。 例如,假设初始状态下堆栈为空,进行一系列入栈操作,依次插入元素A、B、C。此时链表的结构为:头指针 -> A -> B -> C -> 尾指针,同时top指针指向尾指针。若需要执行一次出栈操作,删除尾部元素C后,链表的结构变为:头指针 -> A -> B -> 尾指针,同时top指针需要更新为指向尾指针,即top指针指向元素B,表示此时B为堆栈的栈顶元素。 通过设置top指针指向链表尾指针,可以方便地进行入栈和出栈操作,同时保持堆栈的结构和功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值