设head指向一个非空单向链表,逆向输出所有结点数据域的值

6 篇文章 0 订阅

//设置岗哨的方法

#include<stdio.h>
#include<stdlib.h>
#define SIZE 10
typedef struct node{
 int data;
 struct node *next;
}ElemSN;
ElemSN *Createlink(int a[])
{
 ElemSN *h=NULL,*np;
 for(int i=SIZE-1;i>=0;i--){
  np=(ElemSN *)malloc(sizeof(ElemSN));
  np->data=a[i];
  np->next=h;
  h=np;
 }
 return h;
 } 
 void Prelink(ElemSN *head)
 {
  ElemSN *p,*endl=NULL;
  while(endl-head){//判断岗哨位置是否等于head
  for(p=head;p->next-endl;p=p->next);//每次让p跑到岗哨前驱
  printf("%4d",p->data);
  endl=p;//每次将岗哨前移
 }
 }
int main()
{
 int i;
 int *a;
 ElemSN *head=NULL;
 a=(int *)malloc(SIZE*sizeof(int));
 //输入数组值
 for(i=0;i<SIZE;i++)
 {
  scanf("%d",a+i);
  } 
  //创建单向链表 
 head=Createlink(a);
 //逆向输出 
 Prelink(head);
  free(a);
 return 0;
 }

//用栈实现

 #include<stdio.h>
 #include<stdlib.h>
 #define SIZE 10
 typedef struct node{
  int data;
  struct node *next;
 }ElemSN;
 ElemSN *Createlink(int a[])
{
 ElemSN *h=NULL,*np;
 for(int i=SIZE-1;i>=0;i--){
  np=(ElemSN *)malloc(sizeof(ElemSN));
  np->data=a[i];
  np->next=h;
  h=np;
 }
 return h;
 } 
 void Prelink(ElemSN *head,int top)
 {
  ElemSN **s;//指针s指向栈空间,栈空间存取结点地址
  ElemSN *p;
  s=(ElemSN **)malloc(SIZE*sizeof(ElemSN *));
  for(p=head;p;p=p->next){
   s[++top]=p;//入栈
  }
  while(top!=-1){
   p=s[top--];//出栈
   printf("%4d",p->data);
  }
 }
 int main()
 {
  int top=-1;
  int *a;
  a=(int *)malloc(SIZE*sizeof(int));
  ElemSN *head=NULL;
  for(int i=0;i<SIZE;i++)
  {
   scanf("%d",a+i);
  }
  //创建链表
  head=Createlink(a);
  //实现要求的功能
  Prelink(head,top);
  free(a);
  return 0;
 }
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/*带头结点头文件 hlinklist.h*/ #include <stdio.h> typedef int datatype; typedef struct link_node { datatype data; struct link_node *next; }node; /*初始化链表*/ node *init() { node *head; head=(node *)malloc(sizeof(node)); head->next=0; return head; } /*尾插法创建一个带头结点链表*/ node *creat(node *head) { node *r,*s; int x; r=head; printf("在新链表中输入数据以0结束:"); scanf("%d",&x); while(x) { s=(node*)malloc(sizeof(node)); s->data=x; r->next=s; r=s; scanf("%d",&x); } r->next=0; return head; } /*打印链表结点*/ void print(node *head) { node *p; p=head->next; if(!p) printf("链表内容为空!"); else while(p) { printf("%5d",p->data); p=p->next; } printf("\n"); } /*在单链表中查找第i个结点的地址*/ node *find(node *head,int i) { node *p=head; int j=0; if(i<0) {printf("不存在!");return 0;} if(i==0) return head; while(p&&i!=j) { p=p->next; j++; } return p; } /*在带头结点的单链表第i个位置后插入一个数*/ node *insert(node *head,int i,datatype x) { node *p,*q; q=find(head,i); if(!q) { printf("插入的位置不存在!\n");return head;} else { p=(node *)malloc(sizeof(node)); p->data=x; p->next=q->next; q->next=p; } return head; } /*在带头结点的单链表中删除一个为x的*/ node *dele(node *head,datatype x) { node *pre=head,*p; p=head; while(p&&p->data!=x) { pre=p;p=p->next; } if(p) { pre->next=p->next; free(p); } return head; } /*把带头结点的单链表倒置(以结点形式 )*/ node *Dao_zhi(node *head) { node *p,*s; p=head->next; head->next=NULL; while(p) { s=p; p=p->next; s->next=head->next; head->next=s; } return head; } /*删除链表中重复的结点 */ node *dele1(node *head) { node *pre,*p,*q; if(head->next==0||!head->next->next) { printf("链表为空!"); return head; } //pre=head->next; q=head->next; while(q) { pre=q; p=q->next; while(p) { while(p&&q->data!=p->data) { pre=p;p=p->next; } if(p) { pre->next=p->next; free(p); } p=pre->next; } q=q->next; } return head; }
### 回答1: 算法如下: 1. 定义指针p和q,分别指向链表的第一个结点和第二个结点。 2. 循环遍历链表,直到q指向链表的最后一个结点。 3. 如果p结点数据等于q结点数据,则删除q结点,并将q指向一个结点。 4. 如果p结点数据不等于q结点数据,则将p指向q,q指向一个结点。 5. 返回链表的头结点。 代码实现如下: struct ListNode* deleteDuplicates(struct ListNode* head) { if (head == NULL || head->next == NULL) { return head; } struct ListNode *p = head, *q = head->next; while (q != NULL) { if (p->val == q->val) { p->next = q->next; free(q); q = p->next; } else { p = q; q = q->next; } } return head; } ### 回答2: 这道题的主要思路就是遍历整个链表,如果出现相同的数据,就删除后面的那个结点。由于链表中的结点数据非递减链接,所以我们只需要比较当前结点与下一个结点数据是否相等即可。 具体的算法步骤如下: 1. 首先判断链表是否为空,如果为空则直接返回。 2. 定义两个指针p和q分别指向链表的头结点和第二个结点。 3. 遍历整个链表,如果当前结点数据与下一个结点数据相等,则删除下一个结点,将p指向一个相同数据结点,q指向p的下一个结点;如果当前结点数据与下一个结点数据不相等,则将p和q各后移一个结点。 4. 最后返回链表的头结点。 下面是具体的代码实现: void delete_repeat_nodes(ListNode *head) { if (head == nullptr || head->next == nullptr) { return; } ListNode *p = head; // 指向一个不重复的结点 ListNode *q = head->next; // 指向p的下一个结点 while (q != nullptr) { if (p->val == q->val) { p->next = q->next; // 删除q结点 delete q; q = p->next; // 继续判断后面的结点 } else { p = p->next; q = q->next; } } } 这个算法的时间复杂度为O(n),其中n为链表的长度,因为需要遍历整个链表一次。空间复杂度为O(1),因为只需要定义几个指针变量用来遍历链表,不需要额外的存储空间。 ### 回答3: 要删除链表数据相同的多余链结点,我们可以使用双指针来遍历链表,同时使用一个哈希表来记录已经出现过的数据。 具体来说,我们可以定义一个指针p和一个指针q,初始时它们都指向链表结点。然后我们在哈希表中记录下第一个结点数据,即head->val。接着,我们让q指针向后移动一个结点,判断它的数据是否出现过。 如果q指向结点数据出现过,那么我们就将此结点删除,即将p指针的next指向q的下一个结点,并释放q结点的内存空间。否则,我们就在哈希表中记录下q结点数据,并将p指针和q指针同时向后移动一个结点。 当q指针遍历完整个链表之后,我们就可以得到一个没有多余链结点链表了。 具体算法实现如下: 1. 初始化哈希表和双指针p和q,让它们都指向结点。 2. 在哈希表中记录下头结点数据。 3. 如果q指针不为NULL,则继续遍历链表。 4. 如果q指向结点数据出现过,则将此结点删除;否则,在哈希表中记录下q结点数据。 5. 将p指针和q指针同时向后移动一个结点,继续遍历链表。 6. 返回新的链表结点。 代码实现如下: struct ListNode* deleteDuplicates(struct ListNode* head) { if (head == NULL) return NULL; struct ListNode* p = head; // p指针指向当前节点的前一个节点 struct ListNode* q = head->next; // q指针指向当前节点 unordered_map<int, bool> hash; // 哈希表存储已经出现过的 hash[head->val] = true; while (q) { if (hash[q->val]) { p->next = q->next; free(q); } else { hash[q->val] = true; p = q; } q = p->next; } return head; } 这个算法的时间复杂度是O(N),其中N是链表中的结点数。空间复杂度也是O(N),因为我们需要使用一个哈希表来记录已经出现过的数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值