#include<stdlib.h>
struct LNode{
int data;
LNode *next;
};
//初始化链表
void initlist(LNode *&l)
{
l=(LNode*)malloc(sizeof(LNode));
l->next=NULL;
}
/*
//创建链表(尾插法) 正序
void creat(LNode *l)
{
LNode *p,*q;
q=l;
p=new LNode();
scanf("%d",&p->data);
while(p->data!=-1)
{
p->next=NULL;
q->next=p;
q=p;
p=new LNode();
scanf("%d",&p->data);
}
}
*/
//创建链表(头插法)倒序
void creat(LNode *l)
{
LNode *p,*q;
q=l;
p=new LNode();
scanf("%d",&p->data);
while(p->data!=-1)
{
p->next=q->next;
q->next=p;
p=new LNode();
scanf("%d",&p->data);
}
}
//遍历链表
void traver(LNode *l)
{
LNode *p;
p=l->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
}
//链表的插入
void insert(LNode *&l,int x,int pos)
{
LNode *p,*q;
p=l;
int i=1;
while(p!=NULL&&i<pos)
{
p=p->next;
i++;
}
q=new LNode();
q->data=x;
q->next=p->next;
p->next=q;
}
//单链表的删除(给定位置的节点)
void Delete(LNode *&l,int pos)
{
int i=0;
LNode *p,*q;
p=l->next;
while(p!=NULL&&i<pos)
{
p=p->next;
i++;
}
p->next=p->next->next;
}
//删除单链表中所有值为data的节点
void Delete1(LNode *&l,int x)
{
LNode *p,*q;
q=l;
p=q->next;
while(p!=NULL)
{
if(p->data==x)
{
q->next=p->next;
free(p);
p=q->next;
}
else
{
p=p->next;
q=q->next;
}
}
}
//返回单链表的长度
int lenth(LNode *l)
{
LNode *p;
int i=0;
p=l;
while(p!=NULL)
{
p=p->next;
i++;
}
return i-1;
}
//返回指定节点位置
int getpos(LNode *l,int pos)
{
LNode *p;
p=l;
int i=1;
while(p!=NULL&&i<=pos)
{
p=p->next;
i++;
}
return p->data;
}
//对单链表从大到小进行排序
void sort(LNode *l)
{
LNode *p;
int i,j,t;
int len=lenth(l);
p=l;
for(i=0;i<len-1;i++)
{
p=l;
for(j=i;j<len-1;j++)
{
if(p->data<p->next->data)
{
t=p->data;
p->data=p->next->data;
p->next->data=t;
}
p=p->next;
}
}
}
//有序链表的合并
void hebing(LNode *&l1,LNode *&l2)
{
LNode *l,*p,*p1,*p2,*q;
l=new LNode();
l->next=NULL;
p=l;
p1=l1->next;
p2=l2->next;
while(p1!=NULL&&p2!=NULL)
{
if((p1->data)<(p2->data))
{
p->next=p1;
p=p->next;
p1=p1->next;
}
else
{
p->next=p2;
p=p->next;
p2=p2->next;
}
}
if(p1==NULL)
{
p->next=p2;
}
else if(p2==NULL)
{
p->next=p1;
}
q=l->next;
while(q!=NULL)
{
printf("%d ",q->data);
q=q->next;
}
}
int main()
{
int m,n,a;
LNode *t;
initlist(t);
creat(t);
traver(t);
printf("\n");
scanf("%d %d",&m,&n);
insert(t,m,n);
traver(t);
scanf("%d",&a);
Delete1(t,a);
traver(t);
printf("\n");
printf("%d",lenth(t));
printf("\n");
printf("%d",getpos(t,a));
sort(t);
traver(t);
return 0;
}
链表:
【1】链表中倒数第K个 结点
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
示例:
给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* getKthFromEnd(struct ListNode* head, int k){
struct ListNode *p,*q;
int l = 0,t,i = 0;
p = head;
q = head;
while(p){
l++;
p = p ->next;
}
t = l - k + 1;
while(q){
i++;
if(i == t) break;
q= q->next;
}
return q;
}
【2】合并两个链表
给你两个链表 list1 和 list2 ,它们包含的元素分别为 n 个和 m 个。
请你将 list1 中下标从 a 到 b 的全部节点都删除,并将list2 接在被删除节点的位置。
下图中蓝色边和节点展示了操作后的结果:
1.找到链表1的第a-1个节点
2.找到链表1的第b+1个节点
3.找到链表2的尾节点
4.将链表2插入到链表1的第a个和第b个节点之间
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeInBetween(struct ListNode* list1, int a, int b, struct ListNode* list2){
struct ListNode *p,*q,*t;
int k = 0, l = 0;
p = list1;
q = list1;
t = list2;
while(p){
k++;
if(k == a) break;
p = p ->next;
}
while(q){
l++;
if(l == b + 1) break;
q = q->next;
}
q = q->next;
while(t->next){
t = t->next;
}
//t = t->next;
p->next = list2;
t->next = q;
return list1;
}
【3】反转链表
给你单链表的头节点 head
,请你反转链表,并返回反转后的链表。
头插法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
struct ListNode *p,*q,*t;
if(head == NULL) return NULL;
if(head -> next == NULL) return head;
p = head -> next;
head -> next = NULL;
while(p){
q = p -> next;
p -> next = head -> next;
head -> next = p;
p = q;
}
t = head;
while(t -> next){
t = t->next;
}
q = head -> next;
head -> next = NULL;
t -> next = head;
return q;
}
【4】合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
示例1:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
struct ListNode *p,*q,*t;
struct ListNode *l = (struct ListNode *)malloc(sizeof(struct ListNode));
p = l1;
q = l2;
t = l;
while(p && q){
if(p -> val < q -> val){
t -> next = p;
p = p -> next;
}else{
t -> next = q;
q = q -> next;
}
t = t -> next;
}
t -> next = p ? p : q;
return l -> next;
}
【5】奇偶链表
给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。
第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。
请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。
你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* oddEvenList(struct ListNode* head){
if (!head || !head->next) return head;
//odd--奇数 even--偶数
struct ListNode *odd,*even,*odd_end,*even_end,*p;
even = head;
even_end =head;
odd= head -> next;
odd_end = head -> next;
/*
奇数结点指向第一个结点,偶数结点指向第二个结点
移动奇数结点到偶数结点的下一个
偶数结点移动到奇数结点的下一个
最后连接到一起
*/
while(odd_end -> next && even_end -> next){
odd_end -> next = even_end -> next;
odd_end = odd_end -> next;
even_end -> next = odd_end -> next;
even_end = even_end -> next;
}
odd_end -> next = even_end;
return odd;
}