#include<stdio.h>
#include<stdlib.h>
//结点的数据类型
typedef struct Node{
int data;
struct Node*next;
}Node;
//链表类型
typedef struct List{
Node *head;
}List;
//1创建节点
Node* CreateNode(int data){
Node* PtrNode=malloc(sizeof(Node));
PtrNode->data=data;
PtrNode->next=NULL;
return PtrNode;
}
//2向头结点位置插入新结点
void PushHead(List *list,int data){
Node*PtrNew=CreateNode(data);
PtrNew->next=list->head;//如果链表有节点 list->head是一个节点的地址
list->head=PtrNew;//如果链表中无节点
}
//3.1遍历链表 参数为List* 型
void tralve(List*list){
printf("链表中的元素为:");
Node *PtrHead=list->head;//操作时指针指向可能发生变化
if(!PtrHead){
puts("空");
}
while(PtrHead){
printf("%d ",PtrHead->data);
PtrHead=PtrHead->next;
}
printf("\n");
}
//3.1遍历链表 参数为Node* 型
void tralveNode(Node*head){
printf("链表中的元素为:");
Node *PtrHead=head;//操作时指针指向可能发生变化
if(!PtrHead){
puts("空");
}
while(PtrHead){
printf("%d ",PtrHead->data);
PtrHead=PtrHead->next;
}
printf("\n");
}
//4 计算结点个数
int length(List*list){
int count =0;
Node *PtrHead=list->head;
while(PtrHead){
count++;
PtrHead=PtrHead->next;
}
return count;
}
//5 向指定的位置插入数据
int insert(List*list, int position,int data){//position 0 1 2 3 4 ...
if(position<0||position>length(list)){
printf("插入位置不合法系统将默认向头节点插入\n");
position=0;
}
Node*PtrNew=CreateNode(data);
if(0==position){
PtrNew->next=list->head;
list->head=PtrNew;
return 0;
}
Node*PtrHead=list->head;
int i;
for(i=0;i<position-1;i++){
PtrHead=PtrHead->next;
}
PtrNew->next=PtrHead->next;
PtrHead->next=PtrNew;
}
//6 向尾部插入
void PushTail(List *list,int data){
insert(list,length(list),data);
}
//7删除指定的位置的结点
int delete(List *list,int position){
if(position<0||position>length(list)){
printf("坐标不合法 删除失败\n");
return 0;
}
if(0==position){
Node*PtrHead=list->head;
list->head=list->head->next;
free(PtrHead);
PtrHead=NULL;
return 0;
}
int i=0;
Node*PtrHead=list->head;
for(i=0;i<position-1;i++){
PtrHead=PtrHead->next;
}
Node*PtrTemp=PtrHead->next;
PtrHead->next=PtrTemp->next;
free(PtrTemp);
PtrTemp=NULL;
}
//8删除头结点
void PopHead(List*list){
delete(list,0);
}
//9删除尾结点
void PopTail(List*list){
delete(list,length(list)-1);
}
//10 判空
int empty(List*list){
return list->head==NULL;
}
//11 获取头结点
int GetHead(List*list){
if(!empty(list)){
return list->head->data;
}
return -1;
}
//12 获取尾结点
int GetTail(List *list){
if(!empty(list)){
Node*PtrHead=list->head;
while(PtrHead->next!=NULL){
PtrHead=PtrHead->next;
}
return PtrHead->data;
}
return -1;
}
//13 获取任意位置
void GetElement(List*list,int position){
printf("位置%2d的元素为:",position);
int i;
Node*PtrHead=list->head;
for(i=0;i<position;i++){
PtrHead=PtrHead->next;
}
printf("%d\n",PtrHead->data);
}
//14 销毁链表
void DetroyList(List*list){
while(list->head!=NULL){
Node*PtrHead=list->head->next;//存放所删除元素的next的值 也就是所要删除元素的下一个结点的地址
free(list->head);
list->head=PtrHead;
}
printf("销毁链表完成\n");
}
//15 链表逆序(循环)
Node*ReverseList1(Node*Ptr){
if((Ptr==NULL)||(Ptr->next==NULL))
return NULL;
Node*Prev =NULL;
Node*Current = Ptr;//1定位
Node*Pnext =NULL;
while(Current){//2备份3逆向4前(prev)移,前移(current)
Pnext = Current->next;//2准备工作:为向后遍历正常进行,先把Current->next存到pnext里 下面current->next会改变指向
Current->next=Prev;//3当前的next指向当前结点的前结点(第一次是current->next指向空(同时也把原头指针置空),第二次就是当前结点的前结点(prev=current首结点))
Prev = Current;//三个临时指针变量向前
Current = Pnext;//当前位置向前移动 重复操作
}
return Prev;//原来的尾结点变成新首结点
}
//16 链表逆序(递归)
Node* ReverseList2(Node *Ptr){
if ((Ptr->next == NULL)||(Ptr==NULL))
return Ptr;
Node*NewHead=ReverseList2(Ptr->next);/*递归 后续结点*/
Ptr->next->next=Ptr;/*回溯 ,被 摘除的首结点要被连接到ptr->next才能完成逆序 后续结点的next(也就是后续元素逆序完后的尾结点要指向前面被拆分的结点) 指向前结点*/
Ptr->next=NULL;//取消正向指针 不然形成了环形
return NewHead;
}
//17 链表(有序)合并
Node *Merge(Node *head1,Node *head2){
Node *p1 = NULL;
Node *p2 = NULL;
Node *head = NULL; //找出两个链表中第一个结点较小的结点,head记录较小结点的头结点
if(head1->data < head2->data){
printf("%d %d\n",head1->data,head2->data);
head = head1;
p1 = head1->next;//下一个位置
p2 = head2;
}
else{
head = head2;
p2 = head2->next;
p1 = head1;
}
Node *pcur = head;
printf("%d\n",pcur->data);//1
//在两个链表中遍历比较,将值较小的结点链接到pcur结点后
while(p1!= NULL && p2 != NULL){
if(p1->data <= p2->data){
pcur->next = p1;
pcur = p1;
p1 = p1->next;
}
else{
pcur->next = p2;
pcur = p2;
p2 = p2->next;
}
}
//将p1或p2剩余的结点链到pcur之后,完成整个合并的过程
if(p1 != NULL)
pcur->next = p1;
if(p2 != NULL)
pcur->next = p2;
return head;
}
int main(){
/*List list;
list.head=NULL;//头指针
PushHead(&list,1);
tralve(&list);
PushHead(&list,2);
tralve(&list);
PushHead(&list,3);
tralve(&list);
// list.head=ReverseList1(list.head);
list.head=ReverseList2(list.head);
tralve(&list);*/
//-------------调试逆序功能
List list2;
list2.head=NULL;//头指针
PushHead(&list2,3);
PushHead(&list2,2);
PushHead(&list2,1);
tralve(&list2);
Node*newhead2 = ReverseList1(list2.head);
tralveNode(newhead2);
Node*newhead22 = ReverseList1(newhead2);
tralveNode(newhead22);
Node*newhead222 = ReverseList2(newhead22);
tralveNode(newhead222);
Node*newhead2222 = ReverseList2(newhead222);
tralveNode(newhead2222);
//----------------------
List list3;
list3.head=NULL;//头指针
PushHead(&list3,9);
PushHead(&list3,8);
PushHead(&list3,7);
tralve(&list3);
List list4;
list4.head = Merge(list2.head,list3.head);
Node*new = list4.head;
tralveNode(new);
/*Node *ptr;
ptr = Merge(list2.head,list3.head);
ptr = ptr->next;
while(ptr != NULL)
{
printf("%d ",ptr->data);
ptr = ptr->next;
}
printf("\n");
/*Node*pNode=ReverseList2(ptr);
while(pNode != NULL)
{
printf("%d ",pNode->data);
pNode = pNode->next;
}*/
// printf("/n");
// tralve(&list4);//这样遍历少了第二组的首结点的值
/*p= p->next;
list4.head = p;
tralve(&list4);*/
/*printf("lenght=%d\n",length(&list));
insert(&list,1,33);
tralve(&list);
PushTail(&list,11);
tralve(&list);
delete(&list,4);
tralve(&list);
delete(&list,1);
tralve(&list);
PopHead(&list);
tralve(&list);
PopTail(&list);
tralve(&list);
PushHead(&list,3);
tralve(&list);
PushTail(&list,1);
tralve(&list);
printf("%s\n",empty(&list)?"链表为空":"链表非空");
printf("头结点元素为:%d\n",GetHead(&list));
printf("尾结点元素为:%d\n",GetTail(&list));
GetElement(&list,0);
GetElement(&list,1);
GetElement(&list,2);
DetroyList(&list);
tralve(&list);*/
return 0;
}