头插法建立链表--逆序输出

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

#define OK 1;
#define ERROR -1;
typedef char elemdata;

typedef struct node {
elemdata data;
struct node *next;
}Lnode,*linklist; //单链表结点类型描述

//创建一个带头结点的单链表(头插法)
Lnode *headcreat()
{
Lnode *h,*p;
elemdata ch;
h = (Lnode*)malloc(sizeof(Lnode));
h->next = NULL;
while((ch = getchar()) != '\n')
{
p = (Lnode*)malloc(sizeof(Lnode));
  p->data = ch;
  p->next = h->next;
  h->next = p;
}

return (h);
}

//取元素
//读取单链表中第i个元素,1<=i<=length(h)
elemdata get(Lnode *h, int i)
{
int j = 1;
Lnode *p;
p = h->next;
while(p && j < i)//移动p,直到p为空,或者j < i
{
  p = p->next;
  j++;
}

if((p != NULL) && j == i)
  return (p->data);
else
  return ERROR;
}

//删除元素
//删除i元素,并返回其值,1<=i<=length(h)  
elemdata delete(Lnode *h, int i)
{
int j = 1;
elemdata e;
Lnode *p, *q;
p = h->next;
while((p->next != NULL)&& j < i-1)
{
  p = p->next;
  j++;
}
if((p->next != NULL) && j == i-1)
{
  q = p->next;
  p->next = q->next;
  e = q->data;
  free(q);
  return e;
}
else
  return ERROR;
}
//插入元素
//第i个元素之前插入一个元素
int insert(Lnode *h, int i, elemdata x)
{
Lnode *p, *s;
p = h->next;
int j = 1;
while(p && j < i - 1)//寻找第i-1个结点
{
  p = p->next;
  j++;
}
if(p && j == i- 1)
{
  s = (Lnode *)malloc(sizeof(Lnode));
  s->next = p->next;
  p->next = s;
  s->data = x;
  return OK;
}
else
  return ERROR;
}

//求链表的长度
int length(Lnode *h)
{
int i = 0;
Lnode *p;
p = h->next;
while(p != NULL)
{
  p = p->next;
  i++;
}
return i;
}
//查找链表中是否存在数据域为x的结点
//若存在返回该结点的指针,否则返回空。
elemdata locate(Lnode *h, elemdata x)
{
Lnode *p;
p = h->next;
while(p&&(p->data != x))
  p = p->next;
if(p)
  return p->data;
else
  return ERROR;
}

//主程序

#include"lklist_1.c"

int main()
{
Lnode* headlist, taillist;
int j = 1, count;
headlist = headcreat();
printf("请输入所创建链表的元素个数:");
scanf("%d", &count);
printf("取单链表中第2个元素:");
printf("%c\n",get(headlist, 2));
printf("删除单链表中第3个元素:");
printf("%c\n",delete(headlist, 3));
printf("在链表中第3个元素之前插入c.\n");
insert(headlist, 3, 'c');
printf("依次输出单链表中的元素:");
for(j = 1; j < count + 1; j++)
{
  printf("%c",get(headlist, j));
}
printf("\n");
printf("链表的长度为:%d\n", length(headlist));
printf("查找链表中是否存在数据域为x的结点:");
if(-1 == locate(headlist, 'x'))
  printf("链表中没有此元素。\n");
else
  printf("%c\n",locate(headlist, 'x'));
return 0;
}

### 使用逆序数据创建单向或双向链表 #### 方法说明 当使用逆序数据构建链表时,可以采用头插法来实现。这种方法的核心在于每次都将新节点插入到链表头部,从而使得最终形成的链表顺序与输入数据的逆序一致[^1]。 对于单向链表,每个节点仅包含一个指向后继节点的指针;而对于双向链表,则需要额外维护一个指向前驱节点的指针。因此,在构建过程中需要注意更新前后节点的关系以保持一致性[^2]。 以下是具体的代码实现: --- #### 单向链表逆序构建 ```java class ListNode { int val; ListNode next; public ListNode(int val) { this.val = val; this.next = null; } } public class SingleLinkedListBuilder { public static ListNode buildReverseList(int[] data) { ListNode head = null; // 初始化为空链表 for (int i : data) { // 遍历数据数组 ListNode newNode = new ListNode(i); // 创建新节点 newNode.next = head; // 将当前节点作为新的头节点 head = newNode; // 更新头节点 } return head; // 返回构建完成的链表头 } public static void printList(ListNode head) { while (head != null) { System.out.print(head.val + " "); head = head.next; } System.out.println(); } } ``` 调用上述方法并打印结果: ```java int[] dataArray = {1, 2, 3}; ListNode result = SingleLinkedListBuilder.buildReverseList(dataArray); SingleLinkedListBuilder.printList(result); // 输出: 3 2 1 ``` --- #### 双向链表逆序构建 ```java class DoublyListNode { int val; DoublyListNode prev; DoublyListNode next; public DoublyListNode(int val) { this.val = val; this.prev = null; this.next = null; } } public class DoubleLinkedListBuilder { public static DoublyListNode buildReverseDoubleList(int[] data) { DoublyListNode head = null; // 初始化为空链表 for (int i : data) { // 遍历数据数组 DoublyListNode newNode = new DoublyListNode(i); // 创建新节点 if (head == null) { // 如果链表为空,设置为头节点 head = newNode; } else { newNode.next = head; // 新节点的下一节点设为原头节点 head.prev = newNode; // 原头节点的前一节点设为新节点 head = newNode; // 更新头节点 } } return head; // 返回构建完成的链表头 } public static void printList(DoublyListNode head) { while (head != null) { System.out.print(head.val + " "); head = head.next; } System.out.println(); } } ``` 调用上述方法并打印结果: ```java int[] dataArray = {1, 2, 3}; DoublyListNode result = DoubleLinkedListBuilder.buildReverseDoubleList(dataArray); DoubleLinkedListBuilder.printList(result); // 输出: 3 2 1 ``` --- ### 关键点总结 - **头插法** 是实现逆序构建的关键技术,它通过不断将新节点置于链表头部来达到反转效果。 - 对于双向链表而言,除了管理 `next` 指针外,还需要同步调整 `prev` 指针以确保链表结构的一致性和完整性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值