链表的插入删除合并

typedef int elemtype; 定义elemtype为int类型

//链表有数据域和指针域

struct lnode{
	elemtype data;
	lnode* next;//指向相同类型的指针 
};
typedef lnode* linklist;  给结构体更名

//链表输出 因为创建的链表含有头结点,所以新设了一个变量p,使p=L->next;如果没有头结点的话,完全可以不设p

void show(linklist L){
	linklist p;
	p=L->next; 
	while(p){
		cout<<p->data<<" ";
		p=p->next;
	}
	cout<<endl;
}  

//链表的初始化
/给链表分配空间 ,即就是创建头结点,给头结点分配空间
新创建的结点,其next指针都不能悬空
输入的时候分 头插和尾插,头插法:每一次在头结点的后面插入数据 即s->next=l->next; l->next=s;两句的顺序千万不能颠倒
尾插法:需要记录链表的尾端 即tail->next=s;tail=s; 把s挂接在尾端
在创建链表的时候若L->NULL是没有头结点的,若L->next=NULL代表是有头结点的
/

void created_L(linklist& L,int n){
	linklist s,tail;
	L=(lnode*)malloc(sizeof(lnode));//创建了头结点 
	L->next=NULL; 
	tail=L;
	for(int i=0;i<n;i++){
		s=(lnode*)malloc(sizeof(lnode));
		s->next=NULL;
		cin>>s->data;
		tail->next=s;
		tail=s; 
	}
//	show(L); 
}

//链表的插入 不像顺序表一样记录位置 ,linklist后面的&可以不用加
//找到第i个元素 因为链表中没有length,所以要时刻预防链表为空的时候即 l->=NULL的时候


void insertlist(linklist L,int i,elemtype e){
	int j=1;
	linklist s,p;
	p=L;
	while(p&&j<i){
		p=p->next;
		j=j+1; 
	} 
	if(j==i){
		s=(lnode*)malloc(sizeof(lnode));
		s->next=NULL; 
		s->data=e;
		s->next=p->next;
		p->next=s;
	}
	show(L);	
} 

//链表的删除

void deletelist(linklist& L,int i,elemtype& e){
	linklist pl,p;
	int j=1;
	p=L;
	while(p&&j<i){
		p=p->next;
		j=j+1; 
	} 
	if(j==i){
		pl=p->next;
		p->next=pl->next;
		e=pl->data;
		free(pl);//删除完释放节点 
	}
	show(L);
} 

//找到指定元素


void getelem(linklist L,elemtype e){
	linklist p;
	p=L->next;
	while(p){
		if(p->data==e)
		cout<<p->data<<" ";
		p=p->next; //不要想的那么复杂,用不到else 
	}	
} 

/*两个链表的合并
la lb升序,合成升序的lc ,la lb比较小的接在lc的尾端,
la lb逆序,合成降序的lc,la lb比较小的插在lc头结点的后面(头插法可以实现逆序)
1.先创建一个新表
*/

void  mergelist(linklist& la,linklist& lb,linklist& lc){
	linklist pa,pb,pctail;
	lc=la;
	pa=la->next;
	lc->next=NULL;	
	pb=lb->next;
	pctail=lc;
	free(lb); 
	while(pa&&pb){
		if(pa->data<=pb->data){
				pctail->next=pa;
		        pctail=pa;
		        pa=pa->next;
		}
		else{
				pctail->next=pb;
		        pctail=pb;
		        pb=pb->next;
		}
	}
		while(pa){
	        	pctail->next=pa;
		        pctail=pa;
		        pa=pa->next;
	}
	while(pb){
		      pctail->next=pb;
		        pctail=pb;
		        pb=pb->next;
	}	

	show(lc);
} 

在main函数中调用

int main(){
	int e=0;
	linklist p,q,m;
	created_L(p,5);
	created_L(q,5);
    insertlist(p,3,8);
    cout<<endl;
	deletelist(p,3,e);
	cout<<endl;
	getelem(p,3);
	cout<<endl; 
    mergelist(p,q,m);
	return 0;
}
### 链表数据结构的操作方法 #### 创建有序链表 为了创建两个有序链表,可以定义一个节点类 `Node` 和一个用于管理这些节点的链表类 `LinkedList`。对于每一个输入的整数序列,在遍历过程中按照升序插入到对应的链表中。 ```cpp struct Node { int value; Node* next; Node(int val) : value(val), next(nullptr) {} }; class LinkedList { public: Node* head; LinkedList() : head(new Node(0)) {} // 哨兵头结点 void insertInOrder(int val); }; ``` 当实现了上述功能之后,就可以通过读取给定的两组整数序列来构建两个有序链表[^1]。 #### 合并两个有序链表 合并两个已排序的单向链表可以通过比较两个列表头部元素大小的方式来进行。每次选取较小的那个作为新链表的一部分直到其中一个为空为止;最后把剩下的部分接到新的链表后面即可完成整个过程。 ```cpp // Merge two sorted linked lists into one. static Node* mergeSortedLists(Node *l1, Node *l2){ Node dummyHead(-1); // Dummy node to simplify code logic Node *current = &dummyHead; while (l1 && l2) { if (l1->value <= l2->value) { current->next = l1; l1 = l1->next; } else { current->next = l2; l2 = l2->next; } current = current->next; } // Attach remaining nodes from either list current->next = l1 ? l1 : l2; return dummyHead.next; } ``` 此段代码展示了如何有效地将两个已经排好顺序的链表合成为一个更大的有序链表。 #### 插入操作 针对双向链表中的插入操作,则涉及到前驱(`prior`)和后继(`next`)指针的同时更新。下面是一个简单的例子说明怎样在一个指定位置处执行插入动作: ```cpp Status doubleLinkedListInsert(DLinkList& L, int pos, ElemType e) { // ... 查找第pos个位置的具体逻辑 ... auto s = new DLnode(); s->data = e; s->prior = p->prior; s->next = p; p->prior->next = s; p->prior = s; return OK; } ``` 这里假设存在辅助函数能够找到目标位置上的节点p,并且DLnode是代表双向链表节点的数据类型[^2]。 #### 删除操作 同样地,对于双向链表来说,移除某个特定元素也需要调整其前后相邻节点之间的连接关系: ```cpp void deleteElement(DLnode*& elemToDelete) { if (!elemToDelete || !elemToDelete->prior || !elemToDelete->next) throw std::runtime_error("Invalid element"); elemToDelete->prior->next = elemToDelete->next; elemToDelete->next->prior = elemToDelete->prior; delete elemToDelete; elemToDelete = nullptr; } ``` 这段程序片段显示了从双向链表中安全地删除选定元素所需采取的一系列措施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值