带头结点的尾插法建立双链表

带头结点和不带头结点的尾插法建立双链表

一.带头结点的

先介绍存储数据类型为字符型的

  1. //编程建立双链表(data为字符型数据)13-2-1ex3.cpp  
  2.   
  3. //带头结点的双链表  
  4.   
  5. #include<stdio.h>  
  6.   
  7. #include<stdlib.h>  
  8.   
  9. //#include<string.h>  
  10.   
  11. //#include<conio.h>  
  12.   
  13. //#define E_DEBUG  
  14.   
  15. #ifdef E_DEBUG  
  16.   
  17. #define    PRINT      printf  
  18.   
  19. #else  
  20.   
  21. #define    PRINT(...)                  do{}while(0)      
  22.   
  23. #endif  
  24.   
  25.    
  26.   
  27. typedef char datatype;  
  28.   
  29. typedef struct student  
  30.   
  31. {  
  32.   
  33.          datatype data;  
  34.   
  35.          struct student *next;  
  36.   
  37.          struct student *pre;  
  38.   
  39. }DNode;  
  40.   
  41.    
  42.   
  43. DNode *create()  
  44.   
  45. {  
  46.   
  47.          DNode *head, *p, *s;  
  48.   
  49.          datatype x, cycle=1;  
  50.   
  51.          head=(DNode *)malloc(sizeof(DNode));  
  52.   
  53.          p=head; //如果换成带头节点的链表。这里也不能变,切记,不能变成p=head->next;那就错了  
  54.   
  55.          printf("\nplease input the data:\n");  
  56.   
  57.          while(cycle)  
  58.   
  59.          {  
  60.   
  61.                   scanf("%c",&x); //见后面注意2)  
  62.   
  63. if(x!='#')  
  64.   
  65.                   {  
  66.   
  67.                           s=(DNode *)malloc(sizeof(DNode));  
  68.   
  69.                           s->data=x;  
  70.   
  71.                           PRINT("\n %c", s->data);  
  72.   
  73.                           p->next=s;  
  74.   
  75.                           s->pre=p;  
  76.   
  77.                           p=s;  
  78.   
  79.                   }  
  80.   
  81.                   else  
  82.   
  83.                   {  
  84.   
  85.                           cycle=0;  
  86.   
  87.                   }  
  88.   
  89.          }  
  90.   
  91.          p->next=NULL;  
  92.   
  93.          ///head=head->next;//注意,这两句是不带头结点的双链表必须做的,因为按照算法。输入的第一个数实际上是赋值给了head->next  
  94.   
  95.          //head->pre=NULL;//所以,这就相当于头结点(head)里面没有值,所以要用这两步将head向后移一位,之前那个head就不要了。  
  96.   
  97.          PRINT("\nhead->data:%c\n",head->data);  
  98.   
  99.          return head;  
  100.   
  101. }  
  102.   
  103.    
  104.   
  105. int main()  
  106.   
  107. {  
  108.   
  109.          DNode *p;  
  110.   
  111.          p=create();  
  112.   
  113.          p=p->next; //如果是带头节点的双链表建立,除了少了上面那个函数的末尾的步之外,多了这一步,保证从head的下一个节点输出链表data。  
  114.   
  115.          printf("\nnow out put the double linklist:\n");  
  116.   
  117.          while(p!=NULL)  
  118.   
  119.          {  
  120.   
  121.                   printf("%3c", p->data);  
  122.   
  123.                   p=p->next;  
  124.   
  125.          }  
  126.   
  127.          printf("\n");  
  128.   
  129.                     
  130.   
  131.          system("pause");  
  132.   
  133.          return 0;  
  134.   
  135. }  
以下是一个使用带头结点的单链表实现线性表的示例代码: ```c++ #include <iostream> using namespace std; // 定义链表节点结构体 struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; // 定义线性表类 class List { private: ListNode* head; // 头节点指针 public: // 构造函数 List() { head = new ListNode(0); // 创建头节点 } // 析构函数 ~List() { ListNode* p = head; while (p) { ListNode* q = p->next; delete p; p = q; } } // 头插法构造链表 void createHeadList(int n) { for (int i = 0; i < n; i++) { int x; cin >> x; ListNode* p = new ListNode(x); p->next = head->next; head->next = p; } } // 尾插法构造链表 void createTailList(int n) { ListNode* tail = head; for (int i = 0; i < n; i++) { int x; cin >> x; ListNode* p = new ListNode(x); tail->next = p; tail = p; } } // 按关键字从小到大插入节点 void insert(int x) { ListNode* p = head; while (p->next && p->next->val < x) { p = p->next; } ListNode* q = new ListNode(x); q->next = p->next; p->next = q; } // 删除节点 void remove(int x) { ListNode* p = head; while (p->next && p->next->val != x) { p = p->next; } if (p->next) { ListNode* q = p->next; p->next = q->next; delete q; } } // 查找节点 ListNode* find(int x) { ListNode* p = head->next; while (p && p->val != x) { p = p->next; } return p; } // 获取链表长度 int length() { int len = 0; ListNode* p = head->next; while (p) { len++; p = p->next; } return len; } // 销毁链表 void destroy() { ListNode* p = head; while (p) { ListNode* q = p->next; delete p; p = q; } head = NULL; } // 输出链表 void print() { ListNode* p = head->next; while (p) { cout << p->val << " "; p = p->next; } cout << endl; } }; int main() { List list; int n; cin >> n; list.createHeadList(n); // 使用头插法构造链表 list.print(); // 输出链表 list.insert(5); // 插入节点 list.print(); // 输出链表 list.remove(3); // 删除节点 list.print(); // 输出链表 ListNode* p = list.find(4); // 查找节点 if (p) { cout << "Found: " << p->val << endl; } else { cout << "Not found" << endl; } cout << "Length: " << list.length() << endl; // 获取链表长度 list.destroy(); // 销毁链表 return 0; } ``` 注意:以上代码仅为示例,实际实验报告中应该根据具体要求进行修改和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值